推荐文章|Article

从单体架构迁移到微服务8个关键的思考实践经验

作者 郭蕾

随着微服务架构的持续火热,网络上针对微服务和单体架构的讨论也是越来越多。去年的时候,社区更多的关注点是在二者的区别以及优缺点辨析上,而今年,越来越多的人开始关注如何从单体架构迁移到微服务上。毋庸置疑,微服务的理念正在席卷整个开发者社区,像Netflix、Uber这样的公司都是非常成功的应用案例。

但需要注意的是,实施微服务,也需要付出额外的代价,Martin曾经就说过,除非面对的是一个过于复杂以至于难于管理的单体应用,否则绝对不要考虑使用微服务。大多数的软件系统应该构建为独立的单块程序。确保注重单体应用自身的模块化,而不要试图把它们分离成单独的服务。

普元软件产品部技术经理刘相在微服务架构上有很多的实践和思考,InfoQ记者就单体应用迁移到微服务的8个关键问题对他进行了专访,内容涵盖传统单体式架构的挑战、实施微服务架构的铺垫、改造原则、数据库、中间件、分布式事务、风险规避等。

InfoQ:就你目前的观察来看,企业为什么要从单体式架构迁移到微服务架构?他们遇到的最大的问题是什么?

刘相:我所服务的企业多为传统企业,代码在100万行的项目比比皆是,庞大复杂的项目使得开发、测试、维护、运维极度复杂,在弹性、扩展性、可维护性方面也困难重重。除此之外,传统单体式架构遇到的问题还有:

1、团队接手困难

8年前,我曾接手一个100万行级别的项目,那段经历算是一段噩梦:花了3个月的时间通读一遍代码;每次修改代码心惊胆战,修改一个Bug极可能带来各种隐含的缺陷。

2、臃肿的部署

单体应用每次功能或者缺陷的变更导致重新部署整个应用,这种部署方式影响大、风险高,决定了部署频率低,导致两次发布之间有大量的功能或者缺陷需要进行变更,出错概率增高。

3、局限的弹性与扩展能力

单体应用作为一个强耦合的整体,无法根据业务功能伸缩,只能作为一个整体进行扩展。这造成资源浪费,同时无法针对不同业务模块的特性进行有针对性的伸缩,比如计算密集型服务、IO密集型服务。

4、阻碍技术革新

团队对新技术的渴望是不言而喻的,团队士气会因为持续的关注在巨石应用的技术栈而降低;单体式架构下的组织通常来说技术选型非常单一,团队技术能力相对单薄,团队的吸引力一般。

除此之外,对于服务等级、安全要求、业务监管等多个维度均需要针对不同的服务实现不同的治理,迁移到微服务架构成为必然。

InfoQ:微服务有它固有的优势,但对企业的基础设施以及团队要求也比较高。你认为在企业准备迁移到微服务架构前,需要做好哪些准备?

刘相:企业迁移到微服务架构前,零号原则就是对业务充分了解,大量企业因历史原因导致了解业务系统了的人屈指可数时,就试图转向微服务架构,即使采用最好的技术、工具、架构、团队,最后都会摔得很痛(造成无休止的拆分与变更)。

在充分了解业务的前提下,我认为向微服务迁移,还需在如下三个维度准备:

1、偿还技术债务

自动化测试、持续集成与自动化部署是向微服务架构大规模迁移前必须补偿的技术欠债。微服务架构下,团队管理大量服务,其复杂度和测试难度是几何级增加,利用自动化测试能帮助团队快速有效的验证应用;持续集成与自动化部署保障团队更快速、更容易的修改代码,缺少持续集成和自动化部署,向微服务架构转型过程会异常痛苦。

2、新的架构设计原则

采用微服务架构,应用交付高度复杂化。架构设计原则需要从原来单体式架构下的关注功能、性能等维度向MVP(最小可用产品)、面向失败的设计(拥抱失败,而不是阻止失败)、宽进严出(对请求宽进严出,对外的响应要严格规范化)、宁花机器一分,不花人工一秒(自动与自助、复杂重复的事情交给平台工具去做,让程序员去做更有价值的事情)、一切皆资源等设计原则转变,形成架构渐进优化的设计风格。

3、团队变革

《Exploring the Duality Between Product and Organizational Architectures》书中给了一个很有意思的观点,组织的耦合度与系统的模块化成正比。即组织耦合度越高,所开发的产品耦合度越高;组织耦合度越低,所开发的产品耦合度也越低。微服务架构本质上在强调松耦合的架构,因此在微服务架构迁移前,我们有必要对组织进行微调(不要变革,对组织影响很大),确保独立的、小的团队交付一个微服务,同时小团队是微服务的Owner(除了负责开发外,同时负责测试和运维)。这会极大提供团队的责任感,加速微服务的自治和交付能力。

InfoQ:在整个的架构改造过程中,你觉得有哪些可以遵循的规则?

刘相:微服务架构改造原则业界已经总结非常多了,包括:基于业务进行拆分、采用自动化文化、去中心化、服务独立部署、服务完全自治、隔离失败、渐进式拆分、避免大规模改造原有代码等原则,这些原则相信关注微服务架构的已经相对清楚。结合我们具体的实践,提供一些实际微服务化改造时经验总结:

1、先分离数据库、后分离服务

数据模型能否彻底分开,决定了微服务的边界功能是否彻底划清。我们已经见过太多直接从服务分离而造成多次重构和返工的案例;

2、采用“绞杀者模式”

对于无法修改的遗留系统,推荐采用绞杀者模式:在遗留系统外面增加新的功能做成微服务方式,而不是直接修改原有系统,逐步的实现对老系统替换;

3、建立统一的日志规范

规范整个系统而非微服务的日志体系,采用标准的日志格式非常便于后续的日志聚合检索,便于整体的视角分析、监控、查看系统;

4、选择成熟框架

同时做两件不可控的事情(微服务改造、新技术的冲击)注定项目成功概率较低,千万避免自己重复发明轮子,尽量选择市面上成熟的开源技术框架进行支撑,比如Spring Boot、Spring Cloud、Netflix、WildFly Swarm、Docker、Kubernetes等框架;

当然还有很多的细节规范,比如前后端分离原则、采用全局唯一流水号原则实现全链路交易跟踪、如何进行服务的文档化管理及服务测试Mock等。

InfoQ:数据库方面是不是有应该做相应的调整?

刘相:这个话题非常有意义,微服务改造,第一件事情就需要针对数据库模型进行拆分,数据模型边界划清后,服务顺利成章容易划清界限。我们实践过程中强烈推荐的原则是一个微服务对应一个库。当然,随着微服务规模壮大,可以针对性的做读写分离;如果单表数据庞大,可以分表来解决。

InfoQ:如何解决分布式事务一致性呢?

刘相:微服务架构下,完整交易跨越多个系统运行,事务一致性是一个极具挑战的话题。依据CAP理论,必须在可用性(Avaliablitity)和一致性(Consistency)之间做出选择。我们认为在微服务架构下应选择可用性,然后保证数据的最终一致性。在我们的实践中总结出了三种模式:可靠事件模式、业务补偿模式、TCC模式。

可靠事件模式:可靠事件模式属于事件驱动架构,当某件重要事情发生时,例如更新一个业务实体,微服务会向消息代理发布一个事件,消息代理向订阅事件的微服务推送事件,当订阅这些事件的微服务接受此事件时,就可以完成自己的业务,可能会会引发更多的事件发布。

业务补偿模式:补偿模式使用一个额外的协调服务来协调各个需要保证一致性的工作服务,协调服务按顺序调用各个工作服务,如果某个工作服务调用失败就撤销之前所有已经完成的工作服务。要求需要保证一致性的工作服务提供补偿操作。

TCC模式:一个完整的TCC业务由一个主业务服务和若干个从业务服务组成,主业务服务发起并完成整个业务活动,TCC模式要求从服务提供三个接口Try(负责资源检查)、Confirm(真正执行业务)、Cancel(释放Try阶段预留的资源)。

三种模式的详细介绍可以参见同事田向阳的微课堂文章:

· 微服务架构下数据一致性保证(一):http://dwz.cn/3TVFHs

· 微服务架构下数据一致性保证(二): http://dwz.cn/3TVHBW

· 微服务架构下数据一致性保证(三):http://dwz.cn/3TVJaB

InfoQ:中间件是否需要做调整,或者重新规划很多新的中间件?

刘相:对于现有中间件,套用Gartner流行的一个词“双模”,比如MySQL、Redis等中间件适合作为微服务独立出现;对于大块头Oracle、DB2数据库或者诸如Queue的产品,不适合作为独立微服务出现,可以采用集成的方式工作。

微服务架构需要和新的中间件平台提供融合,比如IaaS平台、PaaS平台等。当然在微服务框架内部,有大量新的中间件的产品,比如etcd、motan、resteasy、ELK等。

对于中间件的使用,我们一直保持一个原则:业务逻辑放在服务中,尽量保持中间件的简单。

InfoQ:整个改造过程中,你认为应该如何规避风险以保证平滑过度?

刘相:微服务架构迁移在业务上、技术上都充满了挑战。从规避风险的层面来讲,给大家两点建议:

1、重视运营平台建设

在实施微服务改造前,建议先行搭建好运营支撑平台,平台至少提供微服务的编译、集成、打包、部署、配置等工作;如果有能力建议采用PaaS平台,解决微服务从开发到运行的全生命周期管理,同时提供异构环境管理、容器资源隔离与互通、服务伸缩漂移、服务升级与回退、服务熔断与降级、服务注册与发现。平台帮助开发人员解决更多的技术问题,开发人员专注在业务功能的拆分上。

2、从试点入手,逐步推进

为企业的业务应用分级,先从外围应用试点开始;待经验丰富后,进行核心应用当前迁移和大规模的改造。

InfoQ:结合你的实战经验,分享下你认为的从单体式架构迁移到微服务架构过程中的几个关键点?

刘相:结合我们自身的微服务实战经验,迁移过程可以总结出三个关键点:

1.针对业务系统,重新梳理概念模型+数据模型,切分出松耦合、高内聚的微服务,保障项目组在做正确的事情;

2.制定微服务开发规范(包括技术架构,Spring Boot+Motan+etcd+R ESTEasy+Elasticsearch+Docker+Kubernetes是我们的技术架构选型),保障项目组按照统一的开发规范(技术架构)正确做事;

3.微服务拆分之后,最大的挑战来自于运维、监控、故障处理,如果团队没有微服务运行的经验,故障之后无法快速定位、快速回复,会受到更大的业务压力,因此后期的微服务运营平台或者管理平台(具体功能参见问题7中的第一部分)对团队异常重要,需要配套设计及时跟上,支撑微服务的运行管理。