为什么微服务应该是事件驱动

为什么微服务应该是事件驱动_第1张图片

作者:潘吉祥

当我再次意识到事件驱动的作用,是在云原生的时代下,而不是传统单进程开发中。

“顺理成章”的服务调用

关于单体的各种情况我不在这里赘述,这里直接举一个例子来说明:

假如我们开发一个视频类应用,里面有一个视频推荐模块,用户查看推荐的视频的时候,推荐视频会调用视频列表,并传入用户id;然后视频列表调用用户列表获取该用户关注的博主;然后通过博主来过滤出推荐视频的列表,返回给推荐视频,流程如图:

为什么微服务应该是事件驱动_第2张图片

此时,我们的应用是一个单体的,我们使用三个本地的api进行同步配合完成了一个推荐视频的功能。包括所有的功能都是如此实现的。

后来,我们出于各种原因,将单体拆分,形成了服务化(SOA)的架构,如图所示(这样的拆分很大概率是不合理的,但文章的重点不在于讲服务的拆分,如果你对于服务拆分感兴趣,可以关注 DDD)

为什么微服务应该是事件驱动_第3张图片

此时,原来的功能被隔离了,总之是不能像单体一样本地api调用了,这怎么办呢,顺着这样的思路(如何让隔离的功能也像之前一样进行调用),出现了RPC和 RESTFul http调用,于是,一切又回归“美好”。

可是问题在于,无论是RPC 和 RESTFul http,他们解决了功能性的问题,但是本质和单体的调用是有区别的:

单体情况下,这种调用不确定因素只有一个:机器。只要保证机器不崩坏,理论上这个应用就是可用的(当然了你写的bug不会别列入这个不确定因素,因此bug造成的财产损失,需要由你来负责)。

服务化的情况下,网络成为最大的不确定因素,为了保证应用的高可用,我们必须认定网络是不可靠的,它必定会出问题,而且概率不小。如果视频服务或者用户服务任意一个不可用了,那推荐服务就不可用了。

为了保证服务的高可用,我们再次付出不少的努力,引入注册中心、负载均衡、熔断、降级、失败策略……经过不懈努力,我们让应用达到了可接受的可用率。

这样看来,我们没有享受到服务化的全部福利,至少,我们能够感觉到,它和单体的耦合几乎一样严重,同时为了解决这种耦合带来的副作用,我们付出了不小的带价,但这好像让我们很有成就感,因为我们解决了如此复杂的问题(包括文中没有提及但是服务化必须面临的分布式事务问题)!。

你嫌弃原始的风箱生火慢,于是换了煤气灶,不小心把房间给炸了,于是你又盖了一间新房子,看着新房子,露出欣慰的笑容:房子终于盖好了!

服务化的初衷

服务化(SOA)就是一种面向服务的体系架构,在1996年就被Garnter提出,在如今看来思想不可谓超前,那服务化的本质到底是什么,他和微服务到底是什么关系?

关于服务化的本质,《企业IT架构转型之路》一书中提到:“松耦合的服务带来业务的复用,通过服务的编排助力业务的快速响应和创新”。本质就是松耦合,核心的价值就是服务重用。

在我看来,服务化和微服务的关系是理论和实现的关系(无限套娃)。微服务出现之前的企业总线是服务化的另一种实现,两种实现围绕是否中心化分道扬镳,而微服务是去中心化的。

关于松耦合,这是一个标准,既是标准就很难有明确的上限和下限,接口实现类实现了松耦合,三层架构也实现了松耦合,SOA的服务化调用也实现了松耦合,我们不是说上面的服务调用没有实现松耦合,这是个上限的问题,它没有达到更高的上限。不管是上面的例子,还是我们在实际的开发中,都能感觉到。

同时SOA关注点在于架构上的松耦合,而没有规定具体的实现。因此,我们不能把服务调用等同于 SOA,服务调用只是一种最直观的、符合思维习惯的一种实现,但是,这不代表它就是最合适的。

EDA:实现服务化更好的方式

EDA:event driven architecture 事件驱动架构,由SOA概念提出者 Gartner 2003年引入,区别于服务调用(response/request)的模式,事件驱动依赖事件触发的消息流转和订阅达到服务编排的效果。

一样的例子,直接上图:

为什么微服务应该是事件驱动_第4张图片

当用户关注/取消了博主,用户服务处理用户id和对应的关注的博主,发送相关事件;

视频服务订阅,处理用户、关注博主和对应的视频,之后再发送事件;

推荐列表订阅,生成用户和对应推荐视频列表。

当用户访问的时候推荐服务已经有了需要的数据用户对应的推荐的视频地址,可直接返回,并且这些信息是随着用户操作实时变化的,而不是访问时才服务调用加载。

可以看到按照事件驱动的方式,服务之间是高上限的松耦合,即使相关服务挂掉,也不会影响其它服务,通常我们每个服务会对应一个localstory(本地存储),存放事件订阅触发接受到的不属于本服务的相关数据,而且这份数据是实时变化的,而不是用户访问时才变化;而要实现本服务的高可用直接镜像服务即可,我们将应用的高可用处理直接对标事件消息系统即可。只要事件消息系统是可用的,我们的应用就是可用的(包括分布式事务的问题)。

如这节的标题所言,事件驱动是比服务调用更好的微服务实现方式,这里我没有选择妥协,对于服务之间的编排,事件驱动完全可以取代服务调用(request/response),而不是二者共同协作,发挥各自的“优势”,服务调用完全没有可比性。

注意我所说的前提是:企业内部服务之间的编排情况下。在前端数据调用或者对于第三方的不可控系统,服务调用依然不可替代。

 当然了,以上仅仅对事件驱动较为浅层次的介绍,关于它的具体实践模式还是有不少的细节和难度,将会在后续文章给出系列解答。

相关参考:

《云原生架构》

《企业IT架构转型之道》

你可能感兴趣的:(算法,大数据,java,python,人工智能)