微服务的缺陷和应用

微服务是近几年非常火热的架构设计理念,我们需要正确理解微服务,否则如果只是跟风拿来就用,既不会用,也用不好,用了不但没有效果,反而还可能有副作用。

今天我们就来深入理解微服务,如何避开陷阱,设计一个成功的微服务架构

一. 微服务缺陷

1.服务划分过细,服务间关系复杂

服务划分过细,单个服务的复杂度确实下降了,但整个系统的复杂度却上升了,因为微服务将系统内的复杂度转移为系统间的复杂度了。从理论的角度来计算,n 个服务的复杂度是 n×(n-1)/2,整体系统的复杂度是随着微服务数量的增加呈指数级增加的。下图形象了说明了整体复杂度:

服务粒度图

 

粗粒度划分服务时,系统被划分为 3 个服务,虽然单个服务较大,但服务间的关系很简单;细粒度划分服务时,虽然单个服务小了一些,但服务间的关系却复杂了很多。

 2. 服务数量太多,团队效率急剧下降

微服务的“微”字,本身就是一个陷阱,很多团队看到“微”字后,就想到必须将服务拆分得很细,有的团队人员规模是 5~6 个人,然而却拆分出 30 多个微服务,平均每个人要维护 5 个以上的微服务。

3. 服务调用链太长,性能下降

由于微服务之间都是通过 HTTP 或者 RPC 调用的,每次调用必须经过网络。一般线上的业务接口之间的调用,平均响应时间大约为 50 毫秒,如果用户的一起请求需要经过 6 次微服务调用,则性能消耗就是 300 毫秒,这在很多高性能业务场景下是难以满足需求的。

4. 没有自动化吃撑,无法快速交付

如果没有相应的自动化系统进行支撑,都是靠人工去操作,那么微服务不但达不到快速交付的目的,甚至还不如一个大而全的系统效率高。

5.没有服务治理,微服务达到一定数量,后台管理混乱

信奉微服务理念的设计人员总是强调微服务的 lightweight 特性,并举出 ESB 的反例来证明微服务的优越之处。但具体实践后就会发现,随着微服务种类和数量越来越多,如果没有服务治理系统进行支撑,微服务提倡的 lightweight 就会变成问题。

二.微服务最佳实践

     针对微服务拆分过细导致的问题,我建议基于团队规模进行拆分。我认为微服务拆分粒度的“三个火枪手”原则,即 1 个微服务 3 个人负责开发。

      3 个人负责开发一个系统,系统的复杂度刚好达到每个人都能全面理解整个系统,又能够进行分工的粒度。

从团队管理来说,3 个人可以形成一个稳定的备份,即使 1 个人休假或者调配到其他系统,剩余 2 个人还可以支撑。

从技术提升的角度来讲,3 个人的技术小组既能够形成有效的讨论,又能够快速达成一致意见。

“三个火枪手”的原则主要应用于微服务设计和开发阶段,如果微服务经过一段时间发展后已经比较稳定,处于维护期了,无须太多的开发,那么平均 1 个人维护 1 个微服务甚至几个微服务都可以。当然考虑到人员备份问题,每个微服务最好都安排 2 个人维护,每个人都可以维护多个微服务。

三.拆分方法

基于“三个火枪手”的理论,我们可以计算出拆分后合适的服务数量。根据目的的不同灵活地选取不同的拆分方式。接下来我一一介绍常见的拆分方式。

1.基于业务逻辑拆分

这是最常见的一种拆分方式,将系统中的业务模块按照职责范围识别出来,每个单独的业务模块拆分为一个独立的服务。

基于业务逻辑拆分虽然看起来很直观,但在实践过程中最常见的一个问题就是团队成员对于“职责范围”的理解差异很大,经常会出现争论,难以达成一致意见。例如:假设我们做一个电商系统,第一种方式是将服务划分为“商品”“交易”“用户”3 个服务,第二种方式是划分为“商品”“订单”“支付”“发货”“买家”“卖家”6 个服务,哪种方式更合理,是不是划分越细越正确?

导致这种困惑的主要根因在于从业务的角度来拆分的话,规模粗和规模细都没有问题,因为拆分基础都是业务逻辑,要判断拆分粒度,不能从业务逻辑角度,而要根据前面介绍的“三个火枪手”的原则,计算一下大概的服务数量范围,然后再确定合适的“职责范围”,否则就可能出现划分过粗或者过细的情况,而且大部分情况下会出现过细的情况。

例如:如果团队规模是 10 个人支撑业务,按照“三个火枪手”规则计算,大约需要划分为 4 个服务,那么“登录、注册、用户信息管理”都可以划到“用户服务”职责范围内;如果团队规模是 100 人支撑业务,服务数量可以达到 40 个,那么“用户登录“就是一个服务了;如果团队规模达到 1000 人支撑业务,那“用户连接管理”可能就是一个独立的服务了。

2.基于可扩展拆分

将系统中的业务模块按照稳定性排序,将已经成熟和改动不大的服务拆分为稳定服务,将经常变化和迭代的服务拆分为变动服。稳定的服务粒度可以粗一些,即使逻辑上没有强关联的服务,也可以放在同一个子系统中,例如将“日志服务”和“升级服务”放在同一个子系统中;不稳定的服务粒度可以细一些,但也不要太细,始终记住要控制服务的总数量。

这样拆分主要是为了提升项目快速迭代的效率,避免在开发的时候,不小心影响了已有的成熟功能导致线上问题。

3. 基于可靠性拆分

将系统中的业务模块按照优先级排序,将可靠性要求高的核心服务和可靠性要求低的非核心服务拆分开来,然后重点保证核心服务的高可用。具体拆分的时候,核心服务可以是一个也可以是多个,只要最终的服务数量满足“三个火枪手”的原则就可以。

这样拆分带来下面几个好处:

  • 避免非核心服务故障影响核心服务

  • 核心服务高可用方案可以更简单

  • 能够降低高可用成本

4.基于性能拆分

基于性能拆分和基于可靠性拆分类似,将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其他服务。常见的拆分方式和具体的性能瓶颈有关,可以拆分 Web 服务、数据库、缓存等。例如电商的抢购,性能压力最大的是入口的排队功能,可以将排队功能独立为一个服务。

以上几种拆分方式不是多选一,而是可以根据实际情况自由排列组合,例如可以基于可靠性拆分出服务 A,基于性能拆分出服务 B,基于可扩展拆分出 C/D/F 三个服务,加上原有的服务 X,最后总共拆分出 6 个服务(A/B/C/D/F/X)。

四.基础设施

大部分人主要关注的是微服务的“small”和“lightweight”特性,但实际上真正决定微服务成败的,恰恰是那个被大部分人都忽略的“automated”。为何这样说呢?因为服务粒度即使划分不合理,实际落地后如果团队遇到麻烦,自然会想到拆服务或者合服务;如果“automated”相关的基础设施不健全,那微服务就是焦油坑。

微服务基础设施图

看到上面这张图,相信很多人都会倒吸一口凉气,说好的微服务的“轻量级”呢?都这么多基础设施还好意思说自己是“轻量级”,感觉比 ESB 还要复杂啊?

确实如此,微服务并不是很多人认为的那样又简单又轻量级。要做好微服务,这些基础设施都是必不可少的,否则微服务就会变成一个焦油坑,让业务和团队在里面不断挣扎且无法自拔。因此也可以说,微服务并没有减少复杂度,而只是将复杂度从 ESB 转移到了基础设施。你可以看到,“服务发现”“服务路由”等其实都是 ESB 的功能,只是在微服务中剥离出来成了独立的基础系统。

虽然建设完善的微服务基础设施是一项庞大的工程,但也不用太过灰心,认为自己团队小或者公司规模不大就不能实施微服务了。第一个原因是已经有开源的微服务基础设施全家桶了,例如大名鼎鼎的 Spring Cloud 项目,涵盖了服务发现、服务路由、网关、配置中心等功能;第二个原因是如果微服务的数量并不是很多的话,并不是每个基础设施都是必须的。通常情况下,我建议按照下面优先级来搭建基础设施:

  1. 服务发现、服务路由、服务容错:这是最基本的微服务基础设施。

  2. 接口框架、API 网关:主要是为了提升开发效率,接口框架是提升内部服务的开发效率,API 网关是为了提升与外部服务对接的效率。

  3. 自动化部署、自动化测试、配置中心:主要是为了提升测试和运维效率。

  4. 服务监控、服务跟踪、服务安全:主要是为了进一步提升运维效率。

以上 3 和 4 两类基础设施,其重要性会随着微服务节点数量增加而越来越重要,但在微服务节点数量较少的时候,可以通过人工的方式支撑,虽然效率不高,但也基本能够顶住。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值