什么是微内核架构设计?( 三 )


但是还有一种模式 , 就是完全透明的插件化通讯机制 , 如下图:

什么是微内核架构设计?

文章插图
 
Plug-in组件 , 也就是微服务架构中的服务 , 是不能直接通讯的 , 而是需要Core System进行转发 。这样做的好处和微内核架构一样 , 插件相互之间无直接联系 , 彼此之间非常透明 , 例如服务A下线后 , 完全不需要通知其他服务;服务A被替换 , 也不需要通知其他服务;服务A从数据中心1到数据中心2 , 也不用通知其他服务;即便服务N和服务A之间网络不互通 , 两者之间也能通讯 。
这里有个问题:性能问题 。我们都知道 , 两点之间 , 直线段最短 。为何要多绕一下到Core System呢?这就是微内核和宏内核之间的争论之处 , 使用函数调用非常快 , 而进程间的消息通讯则是非常慢的 , 但是这种通过中介进行通讯机制的好处也是非常明显的 。那么如何提升这种基于总线的通讯性能呢?当然有 , 比如选择高性能的二进制协议 , HTTP 1.1这种文本协议就不需要了;采用Zero Copy机制 , 可以快速进行网络包转发;好的网络硬件 , 如RDMA;好的协议 , 如基于UDP的QUIC等 。总结下来 , 和微内核一样 , 这种微服务通讯的性能是可以提升的 。当然如果实在受不了这种性能 , 在关键场景 , 你可以采用Hybrid模式 , 混入一些服务之间直接通讯的设计 , 但只能在性能极致的场景中使用 。
此外 , 插件化架构中的插件组件是各种各样的 , 通讯的机制也各不一样 , 一些是RPC的 , 一些是Pub/Sub的 , 一些是无需ACK的(如Beacon接口) , 还有一些是双向通讯的等等 。当然你可以选择不同的通讯协议 , 但是这里有一个问题 , 就是Core System需要理解这个协议 , 然后才能进行消息路由 。这个时候Core System需要编写大量的Adapter来解析这些协议 , 例如Envoy包含各种filter来支持不同的协议 , 如HTTP、MySQL、ZooKeeper等 , 但是因此Core System就会变得非常复杂且不稳定 。
另外可以选一种通用的协议 , Core System只支持这一种协议 , 各个插件之间都基于该协议通讯 , 至于服务和其他外部系统如何通讯 , 如数据库、github集成等 , 这些Core System并不关心 , 那只是Service内部的事情 。目前比较通用的协议是gRPC , 如K8s内部都会采用该协议 , 另外Dapr也采用gRPC协议做服务集成 , 因为gRPC提供的通讯模型基本可以满足大多数的通讯场景 。当然另外一个就是RSocket , 提供更丰富的通讯模型 , 也适用于Core System这种服务间通讯场景 。对比gRPC , RSocket可以运行在各种传输层上 , 如TCP、UDP、WebSocket、RDMA等 , 相反的 , gRPC目前只能运行在HTTP 2之上 。
三、 服务通讯的延伸前面说到 , 最好由插件化架构设计的Core System作为服务之间消息通讯的路由 , 如果是这样的话 , 就会产生一种Broker模式 , 当然也有可能是Agent 。这里大家一定会想到Service Mesh , 没错 。当然你可以选择Agent Sidecar模式 , 也可以选择中心化的Broker模式 , 这两者的功能都是一样的 , 只是处理的方式不一样而已 。Agent基于服务注册和发现机制 , 然后找到对方服务的Agent , 再进行两个Agent之间的通讯 , 只是省掉服务之间的调用的开销 。但是Broker是集中式的 , 大家都向Broker发送和接收消息 , 不涉及服务注册发现机制 , 不涉及服务元信息推送 , 就是总线结构 。
我现在做的就是基于这种Broker的总线的架构设计 , 在RSocket Broker中 , 也是采用微内核架构设计 , 当然未必做得最好。RSocket Broker核心就是管理注册的服务、路由管理、数据采集等 , 而不会添加过多的功能 , 和Core System的设计理念一样 , 只添加必须的功能 。如果你要扩展整个系统更多的功能 , 如发短信、发邮件、对接云存储服务等 , 需要编写一个Service  , 然后和Broker对接一下 , 再从broker那里收消息(receive) , 处理完毕后再发送(send)给Broker就可以了 。总体结构如下:


推荐阅读