本文转载自微信公众号《程序员DD》,作者翟永超。转载本文请联系程序员DD公众号。昨晚睡觉前,翻了一下几个群聊的聊天记录。发现了一个很有意思的名词“分布式单体”,顺着线索看了之前的聊天记录。由于内容是脏话,我就不发了。大致内容是某公司在做微服务改造,但是改造的不伦不类。形式上看起来像微服务,但本质上还是单体,甚至比单体还差。这种转型现象其实在中国还是比较普遍的。今天我们就来聊聊这个有趣的话题:分布式单体。各位读者,看看你们公司有没有犯过这样的错误?分布式单体为什么不好先想一个问题:从单体转型微服务的时候,你是按照这些步骤做的吗?当然在业务领域,拆分存储,定义各个微服务的边界,改造代码逻辑,将原来的内部服务调用改为dubbo或feign等远程调用。通过这样的改造,我们获得了很多好处,比如:代码库分离,减少解决代码冲突的麻烦。CI/CD分离,每个分离的服务可以独立开发、部署、运行。数据库分离,独立运行。不同的业务模块不会相互影响。这样的操作,我们把一个臃肿的单体应用变成多个精细化的分布式应用,似乎是一种完美的改造?但是微服务的核心目标是这样实现的吗?继续思考下面的问题:代码库是分离的,但是每个服务是独立迭代的吗?是不是每个需求都要协调大量的同步接口?CI/CD是分开的,但是每个版本都是免费的吗?功能的每次发布都延迟了吗?是否要同时发布大量服务?数据库分离了,但是好像有一个服务宕机了,还是导致很多功能不正常?看起来我们收获了很多好处,但是我们的开发效率确实提高了。它有改善吗?虽然以前我们启动单个应用需要3分钟,现在拆分后一个项目启动30分钟,但是我们每次开发调试都需要同时启动几个项目?这样的开发体验真的很爽吗??看似完成了微服务改造,但实际上还是单体应用,只是从原来的集中式实现变成了分布式实现。原来我们只是做了无用功,真正的收益微乎其微。事实上,这样的转型,除了收入低之外,其实带来的弊端更多。如果你的公司这样做了,你是否注意到这样做之后,系统故障的频率似乎更高了?稳定性好像比单体应用还差?(如果没有,真的要感谢你们的运维团队很强大,推荐转发这篇文章给运维团队,面试完这样的转型,是不是更累了?!)为什么会这样改造使系统更不稳定?原因其实很简单。本来,我们在单体应用中,未拆分的远程调用都是内部调用,这种内部调用造成的故障率很小。将这部分内容拆分成远程调用后,每次调用都会增加网络IO。因素,失败率随着每次调用而增加。那么系统的整体故障率会随着系统拥有的同步远程调用的数量增加而增加。当运维团队和开发层面不支持这部分增加的复杂度时,改造后的系统稳定性必然会比原来的单体应用差。所以,这样的改造,不仅没有得到太多的好处,反而会带来很大的稳定性损失。改造的罪魁祸首是造成上述问题的根源。我觉得主要有两个方面:1、域划分不合理,导致同步远程调用过多。这是最根本的问题,也是转型过程中最常见的问题。说实话,这部分是整个改造过程中最难的,因为需要对业务有非常深刻的理解,对系统设计的领域模型、用户行为有足够的理解。拆分的时候尽量减少同步远程调用,用消息的异步交互代替。同时,也可以根据业务需要做适当的数据冗余。这样可以保证各个拆分后的微服务之间能够获得较低的耦合度。由于耦合度较低,我们可以在不进行任何优化的情况下获得较少的分布带来的稳定性损失。后面第二点的工作量会少一些。同时,也可以实现真正的自主开发、部署和运营。2.简单粗暴的实现,缺乏分布式保护机制在很多团队中,由于业务需求多和人员配置少的矛盾,开发者容易对远程调用的保护机制做的不够,比如:接口的限流策略提供者(保护自己不被别人干掉),接口调用者的降级策略(保护业务的高可用性),接口调用者的熔断策略(保护自己不被别人拖死).只有认真对待各个分布式环境中的依赖点,才能解决分布式改造中涉及的诸多问题。但是做好这件??事的核心是要抓住第一点。只有在领域模型上做一个更合理的拆分计划,才能支持开发者做好这件事。否则随意拆分会造成大量的接口调用,如果把压力加在已经压力很大的开发者身上,这部分的开发质量就很难保证。自然地,随着界面复杂度的增加,系统的稳定性开始下降。到头来,开发者会开始在我们群里吐槽……甚至大家会开始怀疑微服务根本不能带来效率的提升!最后想一想,你的微服务变更有没有我这里说的这种情况??或者您还有其他不同的问题吗?欢迎留言区说说你的问题和看法!原文链接:https://mp.weixin.qq.com/s/YN4zGzySLMCx3QoT2t4pbA
