不管是十几年前 SOA 的流行,还是 7、8 年前微服务的大行其道,还是如今云原生的展露锋芒,背后都离不开一件事,程序拆分或者说服务拆分。否则,一个单体应用,以上的这些技术潮流好像都与它没什么关系,只是一个看客。 虽然Z哥我没有从头开始完整地亲历过以上三个时期,但是这三个时期都有过我留下的足迹。所以我想我接下去分享的内容应该对处在云原生时代的大家有所帮助。
/01 拆分有什么好处/
拆分的目的很容易理解,分而治之。本质是将复杂的大问题分解成更简单的多个小问题,从而解决它。 而在拆分之前的单体系统中,我们往往面临着哪些问题呢?
01 数据库瓶颈
所有的业务都由一个数据库承载着,随着业务的发展,数据库日常内存吃紧,时不时还搞出个 cpu 90% + 以示它的怒火。
02 增加人员对开发效率提升的边际效益递减
项目里的代码量从 10 万行,增长到 100 万,再到 1000 万。随着代码量的增加,代码之间的耦合问题越发严重,开发效率明显降低。好吧,效率不够数量来凑。扩招了更多的人进来,但是发现耦合问题更加严重了,经常出现 A 等 B 提交代码,B等 C 提交代码,C 等 A 提交代码的情况……
03 运维成本指数级增加
随着项目参与人员的增加,每天发布程序的次数也增加了。可怕的是,代码量也在增加,导致每次编译发布的时间也增加了,这对开发效率来说是双重打击。每天发布的时间加起来可能就占了半天。 希望你所在的团队不要处在如此痛苦的场景中。
/02 什么时候拆?/
拆分虽好,但也不是万能的灵丹妙药。对于大多数组织来说,一个新系统不适合一上来就按照拆分的思路来做。因为拆分需要基于对当前业务、当前系统、当前环境的理解之上的,而面对一个未来充满未知的新业务,我们当下的信息积累是不够的,如果过早拆分,很容易导致边界划分不合理的情况,这在后续会带来不小的负面作用。甚至,可能这个产品在经过市场验证失败后就被砍了,之前的工作做得再多、再完美,全白费了。
因此相对来说,从一个已有的单体系统中逐步拆分出一个个模块反而容易得多,因为确定性更高。 单体系统和分布式系统对成本与业务复杂度之间的关系是这样的。
因此,在这个临界点附近进行拆分工作的性价比是最高的。
对于如何判断是否达到了这个临界点,我认为至少要符合以下三点中的两点。
/03 拆分前的准备工作/
并不是以上条件满足了就可以拆了。在实际拆分之前,我们要做一些准备工作。这其中最为关键的是两件事:
因为从单体系统到分布式系统不仅仅是技术的升级,更是开发理念的转变。
这两件事的具体就不展开了,前人已经总结过很多了,我就简单罗列一下。在应用拆分这件事上比较适用的是:
另外,分布式系统中常用的基础设施主要是以下这些:
以上这些是必须项,其它可选项还有不少,比如:分布式文件系统、容器管理平台、CI/CD 等等。
/04 拆分思路/
具体的拆分其实就是划分边界的过程。强烈建议通过 DDD 的思想进行。
其中最关键的是「抽象」工作,为了更易理解还是来举个例子说一下。比如,当我们在某某养车平台下单一个保养订单,你说其中的“安装”业务该以什么形式进行交易比较合理?Z哥我认为是将其当作一个普通商品看待,当然该平台也的确是这么做的。如此一来,购买机油机滤和安装服务对用户来说是一样的,很自然地被创建在一笔订单里,而不是两笔订单。 如何评估抽象的好不好呢?可以从以下两个角度来观察。
不过不管怎样,最终你都在抽象程度、成本、复用性这三者之间平衡。
除此之外,我们还可以根据以下三个维度来进行拆分。
好了,总结一下。 这篇呢,Z哥和你分享了我对微服务或者说分布式系统如何拆分的看法。 拆分可以解决单体系统的三个痛点。1. 数据库瓶颈。 2. 增加人员对开发效率提升的边际效益递减 3. 运维成本指数级增加。
但是拆分也不是越早越好,至少符合以下三点中的两点。
然后,拆分前还需要做好两项准备工作。
具体实施拆分的思路,建议以 DDD 的思想来进行。 其实任何事都没有一招鲜吃遍天的方法,随着业务、技术的发展,我们的拆分思路也需要持续迭代。如果你之前这方面的实战经验比较缺乏,不妨从我分享的这些方面入手试试,希望能对你有所帮助。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8