微服务应该有多“微”

https://www.innoq.com/blog/st/2014/11/how-small-should-your-microservice-be/

随着微服务概念的普及,关于“微” 的大小有了很多不同的定义。一个广受开发者支持的定义是,一个微服务应该小到只做一件事。对我个人来说,我并不觉得这是一个有意义的解释—— “一件事”这个概念本身就有不同的理解,它并不能起到有效约束微服务大小的作用。因此,我同样反对那些认为每个独立的服务应该能且仅能实现单一功能的观点。假设,一个方法根据三个输入值来计算输出——你真的认为我们有必要将这个功能抽离成一个微服务并独立部署么?

相反,我认为从另一个角度看待这个问题比较容易获得我们想要的答案。我们举一个例子:一个电子邮件系统。为了尽量简单化这个模型,我们假设它是传统的邮件系统,只有基本特性,如登录、登出,保持用户设置,创建、删除邮件,查看收件箱,创建/修改文件夹,记录通讯录,搜索邮件等。从单体模式的设计角度出发,我们可以用一个应用来实现所有功能。接下来,我们可以用模块化设计的方式将它的功能拆分成模块,比如我们可以用DDD的方式来拆分。当然,我们需要一些其他的依赖来实现某些功能——UI,数据存储,外部搜索系统等。最后,我们可能得到一个六边形或多层结构的单体应用。

所有与这个邮件系统相关的团队都必须紧密联系在一起,一旦应用有任何改变,(几乎)所有人的代码都会受到影响。这种应用被我们成为 All-or-Nothing。并且,我们只能选择运行/不运行整个系统,没法灵活的开启/关闭某些功能。对于某些团队,这样的结构就很好。但,我们假设,你的团队并不满足于这种架构,你们想要将整个应用切分成相对独立,有着自己生命周期的子应用/服务/库。

如何切分?首先,登陆/登出(或者我们成为授权系统)和用户资料这两块可以拆分成单独的服务。并且因为它们在安全上的特殊性,它们也应该被单独考量。邮件和文件夹两者联系很紧密,所以我将它们划分到一个服务(你也可以尝试拆分它们,尽管我个人并不建议)。接下来,如果我们有不同的通讯协议,如web interface, POP3, IMAP, SMAP等, 我会将每个协议的实现部分拆成对应的服务。同样,信息存储,可以被抽离成独立的服务。我们可以将附件与邮件同样作为信息文件存储,这样信息存储就变成了存储服务。带有UI和API的通讯录可以被抽离成一个独立的服务。

最后,我可能将整个邮件系统拆离成15~20个独立服务。对于任意的请求/操作,我们都可以将它映射到若干微服务之上——比如,用户在表格里输入数据之后,点击了一个按钮,数据应该被保存在这个表格里。我们会用3-5个服务组合来处理整个逻辑。

这就是我拆分微服务的思路 —— 按照业务逻辑与迭代频率区分,而非单纯的追求KISS(Keep It Small and Simple).

换言之,我认为将“服务拆分到尽可能小”并不是你的目的。如果你这样做,只能说明你将拆分服务当作了你的首要业务,而忽视了业务之间的交互性。选择更适合自己的模块方式,才是微服务的最佳实践。

Andy

Andy

a lazy and busy guy.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.