巨石应用 VS 微服务
目前微服务架构的应用正在互联网公司如火如荼的发展,非互联网公司也在用新业务,新系统尝试微服务架构的实践。但是,传统应用怎么样?例如很多 J2EE 的巨石应用仍然占据着企业的核心业务,如果改造巨石应用变成微服务应用成为大家关心的话题。
巨石应用的优点
部署包集中,一旦部署好之后,所有的服务都能自动起来,方便测试,并且研发比较容易的去搭建自己,开发环境,很好在自己环境里验证自己写的代码。在项目初期,项目搭建和维护的成本很低,研发效率高,并且语言相对单一,对开发者技能依赖相对较低。
巨石应用的缺点
巨石应用的缺点也比较明显,任何一个修改,即使是很小的 UI 变化,都需要部署整个应用,随着项目越来越大,部署的成本变得很高。并且一旦项目确定了开发语言,很难进行模块解耦,让开发尝试新的开发语言和框架。
按传统的开发方式来看(项目式的开发模式),比如我的目标是开发 Order,Shipping 和 Catalog 3个服务,那么 UI 团队会提供三个服务的开发,业务逻辑团队会提供3个服务的业务代码开发,之前大家都是这样开发,也没什么问题,但时间久了会导致你的业务逻辑越来越臃肿,难以拆分,改了一处,处处受影响。康威定律提到,任何组织在设计一套系统时,所交付的设计方案在结构上都与该组织的沟通结构保持一致。
对于微服务来说,它推荐的是将每个模块产品化开发,一个模块有专门的团队独立负责 UI,逻辑,持久层的开发,通常是2 Pizza 团队 8-12为佳。每个模块负责一件事情。
微服务听起来很美,但如何将巨石应用进行微服务改造呢?
如何进行微服务改造
策略
首先明确解耦策略:
UI 组件化 – 所有可重用的 UI 组件都抽取出来单独管理,做到跨项目级别的重用。
静态内容服务化 – 例如产品目录这样的功能,属于静态内容,可以将它从应用中解耦出来,变成独立部署的服务。
定义边界 – 服务之前要有清晰的边界
单一职责理论 – 服务的能力要单一,像 Unix 的 ls 命令一样明确。
方法
拆分的方法在业界有成熟的理论支撑:Martin Fowler 2004年在一篇博客中写道了微服务改造的绞杀者模式。很多公司基于该理论进行了自己的实践:
偿还技术债务
做微服务改造之前,首先将软件交付的速度提升上去。如果你的团队还没有做好 CI/CD 的自动化,那么你仍然会每天应付上线的工作,根本抽不出时间做系统的重构。先将持续交付的工具链搭建起来,能让机器做的事情就不要让人去做,把这部分时间节省出来,才能够有时间考虑后面的事情。
例如使用 Gitlab + Jenkins + Sonarcube + Artifactory + Ansible 实现自动化的 CI/CD 过程。
识别核心业务
识别核心业务,也就是具备商业价值的业务.比如图中的企业服务系统就是核心业务,而用户,邮件等服务属于通用服务类型,应当被拆分出来供各个模块调用;同时工单系统,办公室相关的业务属于非增值业务,并不带来商业价值。
抽取微服务
例如,我们先将 Catalog 组件作为微服务抽取出来,这里比较重要的一点是 Catalog 组件必须有自己的数据库,缓存,而不是仍然使用之前的数据库。同时将应用内部对 Catalog 的接口调用都转成 HTTP 调用,或者是 RPC 调用。此时需要确保一点,这个服务只处理和 Catalog 相关的内容,不对外提供任何与之无关或者间接相关的接口服务。
数据库解耦
微服务最重要的一点是服务拥有独立的数据库,而做数据库的解耦也是最复杂的,因为涉及到数据的长期迁移工作。
1.首先把模块分离出来,将代码逻辑分离出独立的模块 。
2.其次将数据库分离出来,复制 Schema,通过 Trigger 进行数据复制,而此时的微服务已经具备独立的数据库。
3.迁移 API,去掉复制数据的 Trigger。
4.完成拆分,独立发布微服务。
服务发现
总结
微服务的改进长期的过程,落地微服务之后,能够获得快速独立部署,灰度发布等等很多优势,虽然落地微服务会带来不少成本,但落地之后的收益是非常大的,企业需要评估落地的成本和收益,指定快速,可落地的,适合自身情况的方案做转型。
参考资料
https://www.martinfowler.com/bliki/StranglerApplication.html
https://www.youtube.com/watch?v=iJVW7v8O9BU&t=1839s
注:文章若干图引用来源为 http://insights.thoughtworkers.org/service-split-and-architecture-evolution/
领取专属 10元无门槛券
私享最新 技术干货