2.2 为什么采用微服务架构
2.2.1 单体架构与微服务架构
就像很难用一个绝对的方式去判断架构好坏一样,在大多数场景下,我们也很难从一个外部的视角去判断服务拆分粒度的合理性,需要对上下文非常了解才能做出一个好决策。例如,团队规模多大,代码规模多大,有没有平台化,有没有工具链,是否需要持续交付,团队文化如何等。因此,一个外部的架构师是很难在短时间内将架构规划合理的,这需要一个过程,当真正了解这一切之后,不断权衡才能最终确定。在规划之前,有必要参考表2-1,综合各方面的情况,最终做出决策。
表2-1 单体架构与微服务架构对比
续表
2.2.2 什么时候开始微服务架构
产品初期优先选择单体架构。面对一个新的领域,对业务的理解很难在开始阶段就比较清晰,往往是经过一段时间之后,才能逐步弄清楚。很多时候,从一个已有的单体架构中逐步划分服务,要比一开始就构建微服务简单得多。另外,在资源受限的情况下,采用微服务架构风险较大,很多优势无法体现,性能上的劣势反而会比较明显。
单体、组件化、微服务架构成本趋势[1],如图2-1所示。当业务复杂度达到一定程度后,微服务架构消耗的成本才会体现优势,并不是所有的场景都适合采用微服务架构,服务的划分应逐步进行,持续演进。产品初期业务复杂度不高的时候,应该尽量采用单体架构。
图2-1 单体、组件化、微服务架构成本趋势
摘自Martin Fowler博客[2]的内容简单翻译如下。
当我听到关于使用微服务架构的故事的时候,我注意到了一种通用的模式。
1.几乎所有成功的微服务架构都是从一个巨大的单体架构开始的,并且都是由于单体架构太大而被拆分为微服务架构。
2.几乎在所有我听说过从一开始就构建为微服务架构的故事中,最终都有人遇到了巨大的麻烦。
在服务划分之前,应该保证基础设施及公共基础服务已经准备完毕。可以通过监控快速定位故障,通过工具自动化部署、管理服务,通过服务化框架降低服务开发的复杂度,通过灰度发布提升可用性,通过资源调度服务快速申请、释放资源,通过弹性伸缩快速扩展应用。
2.2.3 如何决定微服务架构的拆分粒度
微服务架构中的微字,并不代表足够小,应该解释为合适。但是“合适”过于含糊,每个人理解的合适都不尽相同。实际上,有时候对于一个对业务理解不够深入,对团队情况又不是很了解的人,根本无权协助确定服务的粒度。况且,就算本团队的架构师,也很难确定粒度。随着业务发展,开发人员水平的提升,粒度可能会发生变化。这是一个磨合的过程,一个不断演进的过程,没有绝对的对与错。
如果实在找不到合适的依据,可以参考表2-2。决策占比是从通用的角度考虑,并不适用所有的情况,某些公司认为团队规模是决定性的,也有些公司认为架构演进是决定性的,还有些公司认为交付速度是决定性的,找到那个你认为的决定性因素,去做合理的拆分即可。
表2-2 微服务拆分粒度决策参考表
2.3 微服务设计原则
在微服务架构的设计过程中,我们应该遵循哪些原则?以下原则在微服务架构中经常被提起,遵循这些原则能够让我们少走弯路。
垂直划分优先原则
应该根据业务领域对服务进行垂直划分,因为水平划分服务可能会导致如下问题。
调用次数更多,导致性能大幅下降。
实现一个功能要跨越更多服务,沟通成本增加。
垂直划分服务可以以最简单的方式缓解上述问题,并且可以让团队从上至下关注业务实现,端到端负责,持续改进。图2-2简单描述了一个按业务领域垂直划分的微服务架构示例,在业务垂直方向切分服务,通过API Gateway聚合内容。
图2-2 垂直划分服务
持续演进原则
服务数量快速增长带来架构复杂度急剧升高,开发、测试、运维等环节很难快速适应,会导致故障率大幅增加,可用性降低。非必要情况,应逐步划分、持续演进,避免服务数量的爆炸性增长。这等同于灰度发布的效果,先拿出几个不太重要的功能拆分出一个服务做试验,如果出现故障,则可以减少故障的影响范围。另外,除了业务服务数量的增加,还需要准备持续交付的工具、微服务框架等,并加强监控。
服务自治、接口隔离原则
尽量消除对其他服务的强依赖,这样可以降低沟通成本,提升服务稳定性。服务通过标准的接口隔离,隐藏内部实现细节。这使得服务可以独立开发、测试、部署、运行,以服务为单位持续交付。
直接访问对方的数据库会造成一定的耦合性,应该尽量避免。
自动化驱动原则
部署与运维的成本会随着服务的增多呈指数级增长,每个服务都需要部署、监控、日志分析等运维工作,成本会显著提升。在服务划分之前,应该首先构建自动化的工具及环境。开发人员应该以自动化为驱动力,简化服务在创建、开发、测试、部署、运维上的重复性工作,通过工具实现更可靠的操作。避免微服务数量增多带来的开发、管理复杂度问题。自动化可以从多个方面节省时间、提高效率,它可以快速跟踪整个交付过程并实时向所有参与者报告这个过程,赋予参与者责任感和成就感。如在研发过程中,推行持续集成的文化就特别重要,而持续集成所依赖的工具就是一种自动化的体现。
很多互联网公司都遵循“一切皆自动化”的原则,特别是存在跨地域的研发模式时,使用自动化工具将是至关重要的,如开源的协作模式。