微服务是近年兴起的一个概念,是指将应用程序设计成一套可以单独部署的服务。 Martin Fowler 是 ThoughtWorks 的首席科学家。他与 ThoughtWorks 首席顾问 James Lewis 合作发表的《微服务》,可谓是了解微服务架构风格的入门必读。近日,Fowler 又提出了 MonolithFirst 策略。
在许多使用微服务架构的案例中,Fowler 注意到了如下两种常见的模式:
- 几乎所有成功的微服务案例都始于分解过大的“单体(monolith)”应用;
- 几乎所有从头构建的微服务系统最后都陷入了麻烦。
Fowler 认为,虽然微服务是一种有用的架构,但由于会产生“微服务佣金( MicrservicePremium )”,所以它只适用于复杂的系统。服务管理成本会减缓项目进度,因此,简单的应用更适合采用单体架构。在此基础上,他提出了 MonolithFirst 策略,其基本思想是:即使应用后续可能受益于微服务架构,但开始时仍然将新应用构建为单体应用。这主要是出于以下两个方面的考虑:
- Yagni 原则——确定软件思路是否有用,最好的方法是创建一个简化版本,然后看它的使用效果。在这个阶段,最重要的是速度,而该原则可缩短反馈周期,避免微服务佣金。
- 明确的有界上下文集合——只有服务存在良好且稳定的边界,微服务才能有效地发挥作用。但是,任何微服务间的功能重构都比在单体架构中难度大,即使是经验丰富的架构师在自己熟悉的领域里,也很难在一开始就恰当地定义出边界,而首先构建一个单体应用有利于明确功能边界。
Fowler 列举了如下几种 MonolithFirst 策略执行方法:
- 仔细设计一个单体应用,留意软件模块划分,包括 API 边界和数据存储方式。做好这些工作后,向微服务切换就相对简单了。
- 开始时采用单体架构,然后逐步从系统边缘剥离出微服务。
- 首先构建一个单体架构作为“牺牲架构(SacrificialArchitecture)”,然后整个的替换掉。
- 以几个粒度较大的服务开始,待功能边界稳定后再分解成细粒度的服务。
对于第一种方法,Fowler 指出,并不是任何一个系统都可以分解成微服务。有许多系统,由于模块之间相互依赖度太高而难以分开。而且,目前为止,他还没有看到多少采用这种方法的成功案例。第二种方法会在微服务架构的内部保留一部分单体架构,新开发功能采用微服务架构模式。对于第三种方法,Fowler 提醒说,“不要害怕构建一个将来会被丢弃的单体应用,尤其是当它能使软件快速推向市场时。”第四种方式可以让团队获得服务开发及管理经验,而粗粒度的服务还能减少服务间的重构,这有利于后续向微服务迁移。
Fowler 承认,他现在还不知道如何确定一个项目是否要使用 MonolithFirst 策略。但同时,他认为,除非团队有适当的微服务系统构建经验,否则,不要从微服务开始构建一个新系统。Sam Newman 是 Fowler 的同事,他分享了一个团队考虑在新项目中使用微服务的案例,感兴趣的读者可以进一步阅读。
Fowler 的文章在Hacker News 上引发了激烈的讨论,许多网友都提出了不同的看法,krisdol 就是其中之一。他认为,Fowler 的观点与他所处的环境有很大的关系。ThoughtWorks 是一家帮助其他公司解决问题的顾问公司,也就是说,他们会在某个公司的单体应用出现问题时提供帮助,将其重构为微服务架构。因此,Fowler 才能得出MonolithFirst 的结论。而实际上,现在已经有许多微服务优先的案例,只是身在顾问公司的Fowler 接触到的可能比较少。所以他的观点是,微服务优先,尤其对小团队而言,比每个人都共享同一个代码库更有助于项目的快速进展。
而有两年微服务开发经验的网友room271 则表达了相反的观点,他认为,在小公司/ 团队中,采用微服务可能不太明智,因为它对技能的要求比较高,会导致得不偿失。但同时,他觉得,MonolithFirst 是顾问公司的立场,因为当单体应用出现问题时,他们可能已经完成项目离开了。
当然,也有许多网友表示支持,认为微服务设计很难上手也很难重构,而且对技能要求太高。网友btilly 就指出,即使不采用MonolithFirst 策略,构建一个原型单体系统也是很有价值的。
感谢徐川对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。
评论