gitbook/从0开始学架构/docs/11207.md
2022-09-03 22:05:03 +08:00

103 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 35 | 微服务架构最佳实践 - 方法篇
专栏上一期,我谈了实施微服务需要避免踩的陷阱,简单提炼为:
* 微服务拆分过细过分强调“small”。
* 微服务基础设施不健全忽略了“automated”。
* 微服务并不轻量级规模大了后“lightweight”不再适应。
针对这些问题,今天我们看看微服务最佳实践应该如何去做。我会分两期介绍这部分内容,今天是微服务架构最佳实践的方法篇,下一期是基础设施篇。
## 服务粒度
针对微服务拆分过细导致的问题我建议基于团队规模进行拆分类似贝索斯在定义团队规模时提出的“两个披萨”理论每个团队的人数不能多到两张披萨都不够吃的地步分享一个我认为微服务拆分粒度的“三个火枪手”原则即一个微服务三个人负责开发。当我们在实施微服务架构时根据团队规模来划分微服务数量如果业务规继续发展团队规模扩大我们再将已有的微服务进行拆分。例如团队最初有6个人那么可以划分为2个微服务随着业务的发展业务功能越来越多逻辑越来越复杂团队扩展到12个人那么我们可以将已有的2个微服务进行拆分变成4个微服务。
为什么是3个人不是4个也不是2个呢
首先从系统规模来讲3个人负责开发一个系统系统的复杂度刚好达到每个人都能全面理解整个系统又能够进行分工的粒度如果是2个人开发一个系统系统的复杂度不够开发人员可能觉得无法体现自己的技术实力如果是4个甚至更多人开发一个系统系统复杂度又会无法让开发人员对系统的细节都了解很深。
其次从团队管理来说3个人可以形成一个稳定的备份即使1个人休假或者调配到其他系统剩余2个人还可以支撑如果是2个人抽调1个后剩余的1个人压力很大如果是1个人这就是单点了团队没有备份某些情况下是很危险的假如这个人休假了系统出问题了怎么办
最后从技术提升的角度来讲3个人的技术小组既能够形成有效的讨论又能够快速达成一致意见如果是2个人可能会出现互相坚持自己的意见或者2个人经验都不足导致设计缺陷如果是1个人由于没有人跟他进行技术讨论很可能陷入思维盲区导致重大问题如果是4个人或者更多可能有的参与的人员并没有认真参与只是完成任务而已。
“三个火枪手”的原则主要应用于微服务设计和开发阶段如果微服务经过一段时间发展后已经比较稳定处于维护期了无须太多的开发那么平均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”相关的基础设施不健全那微服务就是焦油坑让研发、测试、运维陷入我上一期讲的各种微服务陷阱中。
微服务基础设施如下图所示:
![](https://static001.geekbang.org/resource/image/3b/0e/3b4eda0b9786987879a996da1360330e.jpg)
看到上面这张图相信很多人都会倒吸一口凉气说好的微服务的“轻量级”呢都这么多基础设施还好意思说自己是“轻量级”感觉比ESB还要复杂啊
确实如此微服务并不是很多人认为的那样又简单又轻量级。要做好微服务这些基础设施都是必不可少的否则微服务就会变成一个焦油坑让业务和团队在里面不断挣扎且无法自拔。因此也可以说微服务并没有减少复杂度而只是将复杂度从ESB转移到了基础设施。你可以看到“服务发现”“服务路由”等其实都是ESB的功能只是在微服务中剥离出来成了独立的基础系统。
虽然建设完善的微服务基础设施是一项庞大的工程但也不用太过灰心认为自己团队小或者公司规模不大就不能实施微服务了。第一个原因是已经有开源的微服务基础设施全家桶了例如大名鼎鼎的Spring Cloud项目涵盖了服务发现、服务路由、网关、配置中心等功能第二个原因是如果微服务的数量并不是很多的话并不是每个基础设施都是必须的。通常情况下我建议按照下面优先级来搭建基础设施
1.服务发现、服务路由、服务容错:这是最基本的微服务基础设施。
2.接口框架、API网关主要是为了提升开发效率接口框架是提升内部服务的开发效率API网关是为了提升与外部服务对接的效率。
3.自动化部署、自动化测试、配置中心:主要是为了提升测试和运维效率。
4.服务监控、服务跟踪、服务安全:主要是为了进一步提升运维效率。
以上3和4两类基础设施其重要性会随着微服务节点数量增加而越来越重要但在微服务节点数量较少的时候可以通过人工的方式支撑虽然效率不高但也基本能够顶住。
## 小结
今天我为你讲了微服务架构实践中的三个关键点:如何把握拆分粒度、按照什么维度进行拆分、需要什么基础设施支撑,希望对你有所帮助。
这就是今天的全部内容,留一道思考题给你吧,参考文章中提到的方法,思考一下你所在的业务微服务架构是否还有可以改进和提升的空间?
欢迎你把答案写到留言区,和我一起讨论。相信经过深度思考的回答,也会让你对知识的理解更加深刻。(编辑乱入:精彩的留言有机会获得丰厚福利哦!)