Microservices "Microservices" - yet another new term on the crowded streets of software architecture. Although our natural…martinfowler.com
上篇文章其实讨论了一个问题「什么架构适合新项目?」我们从几个点得出一个不那么兴奋的结论:微服务架构其实不适合新项目。
How To Build a System 101 文中提及了两个现象:medium.com
在今天的这篇讨论中,为微服务架构做一下正名,同时更深入的讨论一些微服务相关的话题。
微服务的优势
首先,相比于传统的分层模型、以及库的形式,微服务对于独立部署这件事,支持的更加自然。传统的分层模型和库的架构组织形式里面,当我们修复了一个小 bug、优化某个功能的性能时候,就要将整个系统,或者是依赖这个库的系统做一次升级和部署,而在微服务架构中,我们只需要修改对应服务中的代码即可实现升级。当然,这并不是说你不需要做什么事情,如果这个更新破坏了接口约定,那么其实就需要我们不断优化服务的边界以及接口协议的设计,这也是微服务架构不断追寻的目标之一。
其次,微服务这种代码的物理隔离,通过接口交互的形式,让我们在设计系统的时候,不得不仔细考虑如何划分逻辑,如何设计接口,从而提高了将整个项目变成垃圾桶的门槛。
然后,因为代码仓库的隔离,我们就可以用合适或者团队更加熟悉的编程语言来实现不同的模块。当团队足够大,业务足够复杂,团队成员背景足够复杂的时候,这个优势就不断会被加强。
综上来看,就如上篇文章所述的观点,微服务架构更加适合解决「复杂团队协作」带来的问题,但是并不是解决「复杂系统」带来的问题,因为一切都还是需要建立在良好的边界设计上。反而想做好微服务,还需要我们准备更多的东西,具体要说的话,至少有如下几个问题。
微服务的价格
首先,RPC 的成本要远远高于 In-Process Calls,网络 Round Trip 带来的时间消耗都非常可观。其次,一旦若干模块演变成若干服务之后,重构的成本也会变高很多。
另外,当从 mono 变成分布式服务集群之后,会带来哪些复杂问题呢?
首先,分布式系统的数据一致性,就是一个很复杂的问题,当所有代码和数据都在一起的时候,我们可以利用事务和锁来解决,但是拆分成微服务架构后,要想很好的解决我们就需要引入分布式锁和事务的基本设施,能否用对就更是另外一门玄学了。
其次,分布式系统因为大量节点和网络通信的存在,问题和故障的产生在设计的时候,其实就是一个常态。这样发现问题和定位问题就必须要比单体应用做的更好,但是因为系统的拆分,问题的定位也变的更复杂。对应的我们就需要设计一套故障管理的基础设施,实现指标收集、监控、报警和恢复,防止出现更严重的问题。
然后,因为在微服务架构中,变更变的更加的常见和频繁,而且因为服务拆分,应用本身也变的更多。这就需要一整套 CI/CD 的基础设施来支持管理这些应用以及应用的变更。
除了上述这些问题,还有个非技术层面的问题也需要考虑。当团队和业务变更复杂的时候,必然会产生的一个现象是:
所有的人能考虑到的系统都是有限的,那么所有人在设计一个系统或者功能的时候,就会不自觉地把这个东西放到自己能够触碰到的系统里面去,最后的结果就是软件架构会不断向组织架构收敛。
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.
所以,早期设计的服务架构是否能很好的和组织架构匹配,其中一方发生变化的时候,另一方能否适应这种变化呢?举个例子,如果组织架构不断变化,这个时候早期设计的服务架构会频繁出现 owner 转移,功能转移的问题,不断会带来的问题就是需要返工重构,加上微服务架构本身重构的成本,会造成组织将很多精力花在这件事上,进而影响业务的发展,这样实际上就失去了业务代码和业务架构本身存在的意义了,毕竟业务团队一切都是为了业务。
好了,本来其实是为微服务正名的,但实际上的一番论证下来,还是需要谨慎的去尝试。需要我们具有解决应用不断膨胀的情况下带来的各种分布式系统问题的能力,然后才能更好的开展微服务之路,也才能更好的体会到这一架构模型给团队带来的好处,否则就有点激进了。这些问题包括不仅限于:流畅的 CI/CD 系统、可靠的监控系统、变更管理系统、资源管理平台、良好的组织架构设计。
所以,后续的文章,我想就着这个思路,整理下业内这些问题相关的解决方案设计和实现。也会穿插着一些好玩的技术文章,仅供娱乐了。