服务器 频道

对话朗致集团屠文珂:破解微服务横跨“陷阱”

  医药行业政府管控严格,业务十分复杂,涉及多服务联合协作的问题较多。那么,这类企业的IT架构如何来建?答案是,系统前后端分离,服务端采用微服务架构,同时用系统事件解决微服务横跨陷阱!

  不为微服务架构而架构

  “之所以采用微服务架构,是因为相对SOA单体架构而言,微服务这种组件化、松耦合、自治、去中心化的架构,更灵活、敏捷,更能满足业务需求。” 朗致集团数字化效能总经理屠文珂,在SACC大会期间接受笔者采访时表示,没有一家企业,专门为微服务架构而建架构,而是由业务驱动技术落地的产物。

  基于前后端彻底分离思想,前端是企业自己一整套的大前端体系,服务端以微服务进行具体的服务工程的切分,然后提供一系列API接口,通过网关统一对外提供服务。无论是安卓、iOS、 PC、小程序还是各种浏览器,应用程序只开发一次就可以部署到所有的终端。

▴朗致集团数字化效能总经理 屠文珂

  值得一提的是,微服务并非医药类企业专属,互联网、金融、游戏等具有快速迭代和交付需求的场景,都是微服务的重要应用领域,具有广泛的应用前景。对于大多数企业而言,微服务在提高开发效率、提高系统的可维护性、可扩展性、可用性和可靠性方面,都具有显著优势。当企业把一个大型单体架构拆成各个小的颗粒的时候,会提升企业应对市场变化的能力,对业务需求变化达到天或者小时级别的响应。而不再像之前一样,一个应用版本开发下来,几个月才能上线。所以,从技术应用角度来看,微服务是一个通用型架构,没有特别严格的界限去圈定,哪些业务适合使用微服务,哪些业务不适合。微服务的本质是,通过更合理的分工合作机制,去开发各种各样的软件,以供业务人员去使用。

  微服务具体的实践路径有两个:一、采用Dubbo、SpringCloud等开源微服务框架来构建系统;二、采用自研技术路线来构建微服务体系。不管采用哪种技术路线,最终的目的是简化服务架构,降低服务颗粒。当然,业务拆分过程中,也要注意很多关键点,如果拆分颗粒度过于精细,节点过多,会对运维带来极大挑战,导致企业没有办法进行管理。

  谨防微服务横跨“陷阱”

  在实际微服务架构落地过程中,会遇到各种各样的问题,本质上都可以归结为是海量模块之间的协作问题。如何真正做到微服务的分拆,又不相互影响,不发生实际的耦合?这是一个值得业界深思的话题!

  “当系统拆分了200个微服务,其中超过1/3的微服务,都要调用超过50个其他微服务。微服务的初衷是当需求变更时,少数服务做调整即可满足需求,而上述实际情况造成了实质性的微服务耦合。” 屠文珂发现,微服务拆分的复杂度随着服务数量的增多而呈现几何级倍数增长。并且,这种状况不是某一家企业的问题,在朗致集团每年面试的3000+程序员中,落入此陷阱的技术团队为100%。

  既然微服务无法避免耦合,落地的结果与初衷严重不符,当初为什么还要拆开?这其实是微服务横跨带来的缺陷!

  在解决“横跨缺陷”之前,我们先看看微服务发展历史。微服务是由Peter Rodgers、James Lewis、Martin Flower、Chris Richardson等等一系列架构专家,在2005年左右提出并构建的一整套理论体系。比如:Chris Richardson在《Building Microservices Inter-Process Communication In A Microservices Architecture》论文中,阐述了采用IPC(进程间通讯)的方式,实现各个服务间的协同和互相调用,这一理论奠定了当前微服务的理论基础,之后的Dubbo、SpringCloud、Soul框架都符合这一理论。

  微服务的根本问题就是出在“理论”上,就像很多程序员,直到写完代码后才发现,之前的架构设计存在缺陷,不得不把整个架构推翻重来。说白了,只要理论没有在最后一公里落地到实践,这套理论就存在出问题的可能。所以,微服务的发展脉络是,从最终的实践出发,一路向上找原因,反推之前理论存在哪些瑕疵。

  那么,微服务的“瑕疵”是什么?显然是没有控制住复杂度!如果我们用联线服务之间调用关系的复杂度来表示微服务关系,可以发现服务简单的时候没有任何问题。2个微服务的联线数量是1;3个微服务的联线数量是3;4个微服务的联线数量是6……总结出来一个公式就是n(n-1)/2,也就是说复杂度会随着n的平方而增减,即随着微服务数量而呈几何级数的增长,这就是一种复杂度失控。进程间通讯不是随意的,是严格受限的场景。

  如果跨服务进行通讯,读可以,一个服务可以调用其它服务的读,但不可以调用另一个服务的写接口。也就是说,理论科学家在IPC中描述的各种服务之间互相调用的方法,都只是理论上的可行性,最终落地才发现不行。实战通过血的教训总结出:跨微服务之间可以调用读接口,但严格限制调用写接口。

  用系统事件解决问题

  在业界,对于微服务横跨问题有过激烈的争吵。Bob大叔在《架构整洁之道》中,就对微服务架构提出了非常严厉的抨击,但是他的观点只停留在对“微服务划分的边界不合理”这个阶段。

  事实上,Bob大叔的想法过于理想,他对架构师提出了神一样的要求——能准确预知未来,决策当下。换言之,从边界角度考虑微服务划分,最终导致整个架构根本无法落地。但是,如果找到正确的方法,即便微服务划分不科学、不合理,也能够正常解耦协作,只有做到这一点才算是真正解决了问题。

  所谓“阳光之下无新鲜事”,其实微服务遇到的问题,早在计算机应用发展进程中就已经解决了。以操作系统为例,是海量级别模块的互相协作 ,并且是非耦合的。具体是什么操作的呢?很多人可能没有追踪过:在windows下点击一个按钮,windows会发起超过50个系统事件,而借助操作系统内部的系统事件,windows可以准确描述具体场景时的行为,各模块主动响应各自负责的事件,完成自己的功能职责,进而达成了海量模块间的非耦合协作。

  软件工程师前辈们的智慧,同样适用于微服务场景。微服务理论最大的改进是,对IPC进行严格限制,严格限制跨微服务调用写接口。多服务联合写场景,借助经典智慧模拟操作系统消息体系,构建业务事件体系。各个微服务控制翻转——你不要调用我,我主动响应系统事件去做我应该做的事情,各个微服务主动响应事件,而不是被其它服务调用,这就是解决问题的核心原则。

  以具体的医药行业业务场景为例:如果某个业务员要离职,系统需要干多少事情?首先,要取消业务员的职责,要作废行政认证信息,移出行政组织,然后作废业务员认证信息,将此业务员移出业务组织,取消业务员与客户绑定关系,收回授予业务员的所有销售权,下架业务员上架的所有商品,所有与业务员的商品全部失效,没有例外。一个貌似很简单的离职场景,会有无数的功能扩展,没有极限。因为,医药行业的业务实在太过复杂,并且在今天以及未来,在业务员离职这个节点,业务的逻辑有可能无限调整,作为开发人员要时刻拥抱变化,满足业务端提出的各种需求。

  如果采用服务间调用,会在统一用户中心调用各模块的API。然而,随着业务的扩展,写一个离职功能的人要写无穷无尽的代码,解决各种各样的问题,包括分布式事务逻辑,前后的次序等等。而基于系统事件解决问题的思路,业务员离职时,统一用户中心负责取消业务员角色,只要干这一件事就可以了。当这个事情完成的时候,系统向全局广播一个新的业务事件,就是业务员离职,其它的所有服务主动响应这个事件。认证中心微服务主动负责取消行业业务认证,CRM负责取消业务员和客户的绑定,规则引擎负责收回业务员销售权,商品管理负责下架业务员所有商品。通过这样的方式,实现这样一个复杂业务的控制,以及复杂任务在全系统各个微服务职责的分解和协同。

  “软件系统的瓶颈不在服务端,而在数据库。” 屠文珂强调,企业要想做好微服务,还有一个关键点也很重要,那就是一定要选择好数据库,通过适合自己的数据离散策略去做分库,然后再考虑表结构如何设计,尽可能使全局数据不存在冗余性,否则各个独立的服务非常容易出现数据错乱的状况。

  在微服务落地过程中,通常会产生一个误区,很多团队会把数据库也按照各自的服务拆分,在数据库层也做各自的独立化处理。直到开发末期的时候才发现,数据不仅有拆的需求,还有聚合的需求,不得已再匆匆忙忙做聚合设计,这样会产生100%的冗余,这样程序员在写代码的时候,经常会把数据写错。换言之,由于数据库底层没有控制好,在颗粒度以及冗余设计方面存在问题,导致程序员要付出更大的代价来处理数据冗余问题。

  小结

  任何架构都不是十全十美,微服务架构也一样,但它之所以成为主流趋势,是因为更具备技术优势的独特性。为了满足业务的实时性要求,每年都有大量开发人员选择微服务架构,但大多都会陷入微服务横跨陷阱。朗致集团给出的策略是,在整个方案、架构和代码实践层级实现对程序员的层层减负,负责此超级复杂业务功能的程序员就再也不用担心写错代码被领导批评了,真正从架构上做到不累心,不出错,进而全面提高开发效率。

0
相关文章