在软件架构中,微服务架构自兴起以来被视为应对复杂性、提高系统可扩展性和敏捷性的“救星”。
微服务几乎成为了解决大规模系统问题的首选方案。然而,随着越来越多的企业,尤其是中小型公司,开始引入微服务架构,人们逐渐意识到微服务并非如此。
它不仅未能迅速化解软件复杂性,甚至在某些场景下加剧了问题的严重性。
微服务是否被高估了?
在解决软件复杂度的问题上,微服务确实是被高估了。
它并不能够快速解决业务复杂性带来的软件复杂性,甚至可能会加剧这种情况。
中小型企业过早的引入微服务来解决自己的业务问题,会发现需要构建的基础服务太多。
比如单体服务的日志系统只需要在对应服务的日志文件上就可以查询,而引入微服务后则需要搭建日志系统来追踪全链路的日志方便问题的排查。
微服务虽然能够独立部署,但是如果几个微服务都同属一个团队维护,这种分别部署维护带来的开发阻力会更大。
如果我们能维护一个大而全的仓库,不需要进行频繁的切换,能更专注于业务的实现。
如果是超大型项目和多团队合作,每个微服务只在一个团队内维护,没有了切换带来的繁琐,这个时候微服务就能发挥效用了。
微服务真的好吗?
把系统拆成多个微服务,一旦在某个关键地方依然卡住了业务流程,其整体的稳定性往往还不如单体。
比如在处理 RPC 调用的时候,如果没有处理好网络不稳定带来的错误,很可能会造成整体业务逻辑的失败,要对数据进行回滚的话因为没有事务的保证,反而更容易产生“脏数据”。
能够通过扩展硬件的手段解决的问题,尽量别使用复杂的软件方法,硬件的成本能够持续稳定地下降,而软件开发的成本则不可能。
微服务没有清晰的职责划分,导致扩展性失效,多加机器往往还不如单机。
如果是想通过微服务降低系统的负载,这种做法并不能达到效果。
例如原先在内核代码直接调用的方法,现在因为服务的划分需要通过网络调用,如果拆分出来有 N 个微服务需要执行对应的操作,那么流量负载会被放大 N 倍,那这个时候物理资源就需要成倍的放大。
微服务的核心 — 分而治之
单机中“整体”与“部分”的关系没有物理的划分,系统质量只能靠研发与项目管理措施来尽可能地保障。
少量的技术专家很难阻止大量螺丝钉式的程序员或者不熟悉原有技术架构的外包人员在某个不起眼的地方犯错并产生全局性的影响,不容易做出整体可靠的大型系统。
架构的作用是分层管理复杂度,避免人的时候犯错,让更有经验的人负责更加核心复杂的部分。
微服务最主要的目的是对系统进行有效拆分,实现物理层面的隔离,微服务的核心价值就是拆分之后,系统能够让局部的单个服务有可能实现敏捷地持续更迭,达到分而治之的效果。
上面说到的需要多次调用,通过分治在局部进行改造,对时间不敏感的事件可以用消息队列来处理,削峰填谷来降低网络的压力。
因为操作的合并,可以减少网络传输的压力,但相应的也引入了消息队列、异步处理和批处理的复杂性,要根据实际情况进行选择。
微服务的边界
西方有一句谚语叫作“所有技术上的决策实际都是政治上的决策”(All Technical Decisions Are Political Decisions),这里的 “政治”是泛指如何与其他人协作将事情搞定, “技术”也是泛指所有战术层面行为,并不局限于信息技术。
微服务的上界并非受限于技术,而是受限于人,更准确地说,受限于人与人之间的社交协作。
在公司内的组织架构其实很大程度上对应了微服务的拆分的粒度,如果需要进行团队的拆分,那么仓库继续耦合在一起就显得不合适了,没办法在组内形成自治,所以组织架构的拆分势必会推动技术层面微服务的拆分。
产品在技术上的拆装重构相对容易,但为了做到组织与产品对齐,将某个组织的一部分权利、职能和人员拆分出来,该组织的领导是否愿意;将两个团队合并成一个新的团队,原有的团队负责人要如何安置等。
这些问题不仅需要执行者有良好的社交能力,还需要更上层的决策者充分理解架构演变同步调整组织结构的必要性,为微服务化打破局部的利益藩篱。
所以关于服务拆和不拆、怎么拆,在现实的情况中更多是对应着团队的变化,这也让技术架构会随着业务变化而变化。
但是有一点我们需要特别关注,就是涉及到数据的强一致性。一旦拆分了微服务,我们将无法使用 ACID 来实现事务的一致性,引入分布式事务带来的好处有时会比它带来的问题要多,所以微服务的强一致性应该聚合在同一个微服务内实现。
如果出现了没办法聚合在同一个微服务内实现的话,我们才寻求复杂的技术手段来保证数据的。