Linjun Weng

Technical Notes On Coding and Design

My GitHub

微服务(Microservice)浅谈

13 Jul 2019

最近几年微服务(Microservice)架构在互联网行业非常流行,它不光改变了软件架构的方式,而且还改变了团队协作的方式。工程上没有完美的解决方案,只有解决问题的解决方案。对于微服务架构也是一样,在架构设计的时候不能迷信这种架构方式,把它当作万能钥匙。而是要深入理解这种架构的优劣,并根据实际场景综合考虑,才能实现软件架构的终极目标,即:“软件架构的终极目标是,用最小的人力成本来满足构建和维护该系统的需求。”本文旨在分析微服务架构的优缺点和注意事项,以便自己将来在设计软件架构的时候能够做出正确的决策。

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure. – Melvyn Conway, 1967

微服务架构的对立面是单体架构(Monolithic),我们有必要先来分析单体架构都有哪些缺点?因为微服务的出现很大程度上是为了克服单体架构的这些缺点。

  • 模块之间边界不清晰。单体架构的模块之间的边界很容易被打破,导致它们之间耦合度逐渐变高,最终造成一个模块修改需要重新编译和部署多个相关模块。(这一点现在持怀疑态度,单体架构的模块也可以很清晰。MSTR的Server一开始模块之间的边界是很清晰的,各模块全部通过清晰定义的借口实现依赖,而且约定一般情况下不能轻易修改接口。只是后来在项目的压力之下,程序员的这种约束和自觉被打破了,毕竟代码就在哪里,想改还是能改的。所以,慢慢的边界就没有那么清晰了。)

  • 水平拓展困难。在大多数情况下单体架构只能通过垂直拓展(scale vertically)来提升服务能力,无法轻松实现水平拓展(scale horizontally)。(关于这一点和微服务架构相比,单体架构确实没有优势。一方面单体架构只能整体拓展,无法按需拓展遇到性能瓶颈的那部门功能模块。另一方面,一致性问题又会进一步阻碍单体架构的整体水平拓展。在一致性问题方面,MSTR Server 就是一个最好的例子。但话说回来,微服务架构同样存在一致性问题,如果设计不好也会成为水平拓展的最大制肘。)

  • 不支持热更,每次发布需要重启服务器。

  • 不支持部分服务(partial service),任何地方出了问题,大家要死一起死。(感受太深了,噩梦般的core dump就是最好的例证。)

  • 迭代周期长,不够敏捷。具体体现在单体结构的研发团队是按照模块划分的,任何产品层面的更新都需要协调多个Team一起合作,很难做到敏捷迭代。

那么微服务架构是否能够解决上述缺点? 目前关于微服务架构的优点大家提的最多的就是:

  • 松耦合。

  • 独立开发部署。

  • 分布式。

  • 持续集成。

  • 易测试。

  • 性能差。

前两点从栗子云的实践看以上两点都被否定了。分析其原因,首先服务的边界不等于架构的边界,如果组件划分不合理,虽然在形式上各个服务是相互隔离的,但本质山还是高度耦合的。某个对象增加某个属性,会导致一组接口和服务需要修改,而且修改的成本甚至比单体架构还要高。所以,优秀的架构不在于是采用微服务还是单体架构,而在于组件划分是否合理,边界定义是否清晰。另外,在拆分服务的时候,粒度的把握是关键,微服务这个名字很有误导性,很多人以为微服务就是把服务拆的越细越好。比较合理的方式是一开始服务越少越好,并在项目迭代的过程中随着对场景需求认知的逐渐加深,再基于CCP、CRP和REP三条原则将一部分功能模块抽成独立的服务。如果一开始就把服务拆得过细,必然导致灾难,栗子云就是一个最好的例子。

Designing the right level of service component granularity is one of the biggest challenges within a microservices architecture.

关于选用微服务架构目前想到两点注意事项:

  • 一开始不要把服务拆得过细。

  • 事务性服务不适合采用微服务。

If you find you need to orchestrate your service components from within the user interface or API layer of the application, then chan‐ ces are your service components are too fine-grained. Similarly, if you find you need to perform inter-service communication between service components to process a single request, chances are your service components are either too fine-grained or they are not parti‐ tioned correctly from a business functionality standpoint.


Copyright © 2018 Linjun Weng.
Non-commercial re-use with attribution encouraged; all other rights reserved.