啥,你要抛弃单体,拥抱微服务?
Posted supingemail
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了啥,你要抛弃单体,拥抱微服务?相关的知识,希望对你有一定的参考价值。
思考
在业务开发的时候,肯定会面临一个问题,那就是:到底应该使用微服务,还是应该使用单体应用 ?
这个其实没有一个明确的约定,但是可以找一些规律,来确定使用哪种方式进行业务的开发。
使用微服务实现的场景
-
业务很复杂,复杂操作很多,放在一个应用中管理不良;
-
业务功能很独立,任何一类业务都可以单独作为一个子系统,可单独使用;
-
团队成员分工明细,术业有专攻。有擅长订单的,有专攻供应链的,有研究物流的等等,可由他们来单独开发子服务;
-
为了学习和锻炼技术,掌握新知识,这种少数;
以上四种,都可以使用微服务来实践。
那么哪些场景使用单体服务呐?
有这样一种声音很强烈:都什么年代了,还在使用单体应用!每次听到这样的话,我都很不屑,因为不管是单体还是微服务,最终的目的都是为了业务而服务的,如果说使用单体能够更加好,更加稳健的为业务服务,那为什么不用呐 ?
单体应用的场景
1.对一致性要求很高,任何的操作都会使得一致性出现问题,可能引起不好的或是可怕的后果;
2.金融系统,当然前提是这个金融业务场景并不复杂,而且对一致性要求很高;
3.服务相应迅速,并且涉及到同进程,多线程的输入和输出操作。
单体应用,最典型的就是游戏。到目前为止:我从没有听说,游戏使用微服务开发的。
所以:不要一味的以为:微服务是万能的!
业务系统要使用单体还是微服务,不单单是技术的问题,更重要的是:要根据业务来定,要根据实际情况,灵活应用!
单体改成微服务讨论
先思考一个问题:从单体改造到微服务的时候,你们是不是按这样的步骤来的?
确定业务领域,拆分存储,定义各微服务的边界
改造代码逻辑,将原来的内部service调用改成dubbo或feign这样的远程调用
通过这样的改造,我们得到了很多好处,比如:
代码库分开了,减少了麻烦的解决代码冲突的困扰
CI/CD分开了,每个拆分后的服务都可以独立开发、部署、运行
数据库分开了,独立运行,不同业务模块不会互相影响
这样一顿操作,我们把一个臃肿的单体应用变成了多个精炼的分布式应用,似乎完美的实现了改造?但这样就实现了微服务的核心目标了吗?继续思考下面的问题:
代码库是分开了,但每个服务都在独立迭代吗?是不是每个需求都要协调一大堆同步接口?
CI/CD是分开了,但每次发布都是自由的吗?是不是每次功能的发布都拖上了一大推的服务要一起发布?
数据库是分开了,但似乎有个服务挂了,依然导致很多功能就都不正常了?
看似我们得到了很多好处,但我们的开发效率真的得到了提升吗?虽然我们以前一个单体应用启动要3分钟,现在拆分后,一个项目启动30秒,但每次开发调试要同时开好几个项目同时启动?这样的开发体验真的爽到了吗?
看似完成了微服务改造,实则依然是个单体应用,只是从原本的集中式实现,变成是分布式实现。原来我们只是做了一次无用功,真正的收益微乎其微。
而实际上,这样的改造,除了收益不高之外,还带出了更多的坏处。如果你们公司是这样做的,有没有发现,这样做之后,好像系统故障的频率更高了?稳定性似乎比单体应用还差?(如果没有,那一定要感谢你们的运维团队真的很给力,同时建议把这篇转给运维团队,采访下这样的改造是不是他们变得更累了?!)
为什么这样的改造会导致系统更加不稳定呢?其实道理很简单,原本我们在单体应用中,未拆分的远程调用都是内部调用,这个内部调用所能引发的故障率是微乎其微的,而将这部分内容拆成了远程调用后,每一个调用都增加了网络IO的因素,每一次调用的故障率都增加了。那么系统的整体故障率是随着系统拥有多少同步远程调用的数量增加而增加的。当运维团队与开发水平没有支持好这部分增加的复杂度时,那么改造的系统,必然稳定性会比原来的单体应用更差。
所以,这样改造的结果,不但没有得到很多的收益,反而会带来很多稳定性上的损失。
改造走样的元凶
那么为什么会造成上面所说的问题呢?我觉得主要有两方面:
1. 领域拆分的不合理,引出了过多的同步远程调用
这个是最根本的问题,也是在改造过程中最常见的。这部分说实话是整个改造过程中最难的,因为需要对业务有非常深入的认识,对系统设计的领域模型、用户行为有足够的理解。在做拆分的时候,尽可能的减少同步远程调用,取而代之的是走消息的异步交互,同时根据业务需要也可以做适当的数据冗余。这样就能保证,每个被拆分后的微服务之间可以获得更低耦合度。
因为更低的耦合度,我们才能在不做任何优化的情况下,获得更少的分布式所带来的稳定性损失。对于后面要将的第2点的工作量也就越少。同时,对于真正的独立开发、部署、运行也成为可能。
2. 简单粗暴的实现,缺少分布式的保护机制
在很多团队里,因为业务需求多与人员配置少的矛盾之下,开发人员很容易出现对远程调用不做足够的保护机制,比如:接口提供方的限流策略(保护自己不被别人搞死),接口调用方的降级策略(保护业务更高的可用性),接口调用方的熔断策略(保护自己不被别人拖死)。只有认真对待每一个分布式环境下的依赖点,那么才能解决因为分布式改造所牵连出的诸多问题。
但要做好这一点的核心,还是对第一点的把握,只有在领域模型上做更合理的拆分规划,才能支持开发人员做好这个点,不然随意的拆分,一大堆接口调用压给本就压力很大的开发人员,那这部分的开发质量肯定很难保障了,自然而然的系统稳定性就开始随着接口复杂度的增加而不断下降了。最后,开发人员就会开始来我们群里吐槽了...甚至大家也开始怀疑微服务根本带不来效率的提升!
最后,思考一下,你们的微服务改造有出现这里我说的情况吗?还是有其他不一样的问题呢?
DDD
如果系统采用了DDD的设计和实现,那么其实用不用微服务,并不是那么重要了,因为良好的DDD设计,已经很好的处理了业务划分,代码归置,功能解耦的要求了。
想了解DDD的,可以查看我之前写的DDD总结!欢迎讨论和探讨。
了解更多,关注:码出精彩 codingba
以上是关于啥,你要抛弃单体,拥抱微服务?的主要内容,如果未能解决你的问题,请参考以下文章