写点什么

微服务 vs 单体架构

作者:agnostic
  • 2022-11-26
    上海
  • 本文字数:2105 字

    阅读完需:约 7 分钟

最近,对于微服务的讨论,准确来说是检讨似乎突然被推到了聚光灯下,从马斯克对 twitter 渲染一个用户时间线要 100 次服务调用的吐槽,到 infoq 关于微服务发起的讨论,结合前两年 Invision、Git 从微服务退回到单体服务的尝试,似乎针对微服务的负面声音越来越多。实际应该怎样看待微服务呢?


简单的历史

微服务不是凭空出现的,A long time ago,是没有微服务的,那个时候就是单体架构。

大约在本世纪初某一年的冬季,出现了 SOA 的架构,然后 18 摸这些厂商借着东风开始猛推 ESB、BPM 等软件,推着推着基本就把 SOA 这个概念玩坏了。

然后大约在 2010 左右的某一年,开始流行起了微服务架构,Martin Fowler 大师是这个架构的强力拥趸,大家可以看一下他老人家关于微服务的论述:https://martinfowler.com/articles/microservices.html。微服务和 SOA 的区别,个人的浅见在于分布式和集中式,在于服务切分粒度的不同。

在这之后的几年,随着容器技术、网格技术的发展,更近一步的推进了微服务的深入和推广,基本上不管大公司、小公司、菜鸟公司,都开始往微服务、容器化、无服务器、云原生的方向走,生怕错过了风口。


微服务要解决什么问题

从上面的历史可以看出,不管是 SOA、微服务、容器技术的出现,都是要解决软件复杂度的问题。大家试想一下,如果你维护的是一个几千万行代码的单体应用,同时有几百个开发人员在往上面 commit 代码,你的感受如何。


首先,我们从服务特性的视角看。

不同的应用,不同的服务,在服务特性上,会有很大的区别,我们可以从这些维度去考量:

  1. 使用方不同:内部服务、外部服务。

  2. 服务的重要性不同:关键服务、配套服务。

  3. 服务的 SLA 不同:响应时间、可用率指标等。

如果将这些不同特性的服务放在一个应用里面,对于这个应用的技术保障,就会非常困扰。这个服务我们到底是要保证怎样的可用率、怎样的响应速度、怎样的运维等级。


其次,我们从技术架构的视角看。

对于不同的应用,由于特性的不同,背后的技术栈会有明显的区别:

  1. 状态型 vs 流水型:两者在缓存、存储、容灾的设计上会有很大差别。

  2. 实时 vs 离线:这个在计算引擎的选择上,会有很大的分叉。比如一个会选择 flink、一个选择 Hadoop。

  3. 存储型 vs 计算型:在扩容时,两者的策略会有明显差别。

不同类型的应用(服务),背后会有不同的技术栈来支撑,对于应用的技术架构、开发、运维、稳定性保障,都会有差别很大的策略。


最后,我们组织的角度看。

应用(服务)是人开发的,人和人之间的协作是有成本的。如果有太多的人在一个应用上开发,这个应用一定是不可控的。所以,基于我们实践的经验,往往对于应用的拆分,要遵循如下的经验准则:

  1. 一个应用的主要 committer 建议不超过 10 个。

  2. 同一个小组(10~20 人)维护的应用建议不超过 5 个。

  3. 一个应用对外提供的主要服务最好不要超过 20-30。


我们如何选择

所以,对于微服务还是单体的选择,都需要适合业务、组织的特点。不能无视业务和组织的现状做过度超前的布局,也不能无视业务和组织的发展因循守旧。在选择上没有特别的原则,需要结合每个公司自身的特点做最合理的决策。


首先,还是康威定律发挥作用——设计系统的架构受制于产生这些设计的组织的沟通结构。

如果是一个很小的组织,一个初创的公司,完全没必要搞个二三十个应用出来彰显自己业务的复杂性和技术的先进性。只其次是需要将 to C、to B、内部系统、离线服务分开,划分个位数的系统就可以了。

如果业务和团队近一步发展,形成了多个业务团队和技术团队,这个时候可以考虑将应用(服务)根据业务领域进行划分,如网关、商户/用户服务、交易、渠道、资金等。

近一步的,业务发展到需要考虑高并发、高可用、读写分离等,那就需要根据服务的技术特性,状态型/流水型、实时/离线、存储依赖型/计算依赖型、服务 QPS 的要求、服务可用率的要求,等等,进一步对服务进行细分,满足不同的服务 SLA 和扩容策略的需求。


其次,对于一些明显的过度设计,需要避免。像一次交易链路要经过几十个应用的一百多次调用,这样的设计明显就过于臃肿。

  • 机械的划分成产品层和核心层。对于对客的服务,划分成产品层(view)和核心层(model)是合理的。但是对于明显的内部服务,再做这样的划分,就没有太多的必要性。

  • 过度的收口和统一。出现类似 ESB 的组件,所有的调用,都要从这里过一道。

  • 无用的二传手。为了新建应用而新建应用,调用链路拉出来一看,某些系统就承担了一个承上启下透传的作用,这种就是明显可以优化的服务拆分。

  • 过细的服务粒度。比如支付(下单)前的咨询,拆分成商户咨询、用户咨询、日历咨询、手续费咨询、汇率咨询等等过于细碎的服务。


最后,服务的拆分是一个动态的过程,是随着技术、业务和组织的变化而动态变化的。不存在一成不变的服务切分原则。


参考资料

发布于: 刚刚阅读数: 4
用户头像

agnostic

关注

还未添加个人签名 2019-02-14 加入

还未添加个人简介

评论

发布
暂无评论
微服务 vs 单体架构_微服务架构_agnostic_InfoQ写作社区