RSocket云原生架构下的另一种通信协议选择
写在前面
奈飞公司在整个微服务架构体系处于行业领先地位,在其内部有一种自研的通信协议方式,以实现微服务架构下高性能的通信,他就是RSocket。同时在云原生概念盛行的今天,一种可以在service mesh下高性能通信的组件同样也是各个企业需要的,所以今天我们就聊聊RSocket吧。
为什么需要一种新的通信协议?
在微服务,云原生架构盛行的今天,各种服务之间,mesh之间需要进行大量的通信,网络似乎成了整个架构栈中的一等公民。
为减少因网络的不确定性而带来对于整个网络架构系统的影响,降低请求延迟往往需要进行一系列的可用性设计。
而目前常见的网络协议,如HTTP的request-response交互方式,很难有效或高效的进行通信,也很难解决海量请求下对于后端资源有效使用的问题。同时HTTP这种文本协议方式较二进制协议的实现也存在性能问题。
RSocket是什么?
对RSocket吹了一波,那么RSocket究竟是什么呢?
官方定义:RSocket是基于reactive stream flow control的双向,多路,基于消息的,二进制的通信协议。
RSocket是一种新的七层通信协议,某种程度可以认为是HTTP等其他协议的替代方案。较HTTP协议来说,其增加了异步,双向背压,多路复用,断线重连,消息驱动等特点。
由于是Pivatal公司主导的项目,其实现上大量引入了Reactive Stream相关的编程实现。
之前我们Reactive相关文章说过,响应式规范的兴起,目的之一就是为了解决海量终端设备背景下,服务端接受请求过载,超时宕机等问题,通过响应式编程中的背压可以实现这种压力过载的控制。
交互模式分为四种:
request-response:请求响应式,目前基于http请求的模式都是这种。
fire-and-forget:对于那些不关心结果的请求,直接返回。
request-stream:一个请求,可以通过流方式返回多次结果。
channel:服务器可以主动发多个请求到客户端,客户端可以发多个结果给服务器。
特点:
对于请求和响应都可以取消掉,可以释放掉一些系统资源。
如果数据提供方由于某种原因hang住,请求方可以先断开,之后有时间之后再来检查结果。
类似于“背压”的能力,可以根据自己的性能情况控制调用方的频率。
所以其更适合分布式场景下的通信。
在RSocket传输信息中,请求可以划分为一个个的帧,每个帧都包含一个帧头,其中包含:流ID,帧类型,其他数据。帧头后是元数据和有效负载(承载用户数据)。
对于这种帧的流,我们可以使用任何的序列化方式进行处理,比如JSON,Protobuf或avro等。
除了这种在协议文本上下功夫之外,其多路复用模型也是其可以进行高效通信的原因。
在请求中,每个流都有一个唯一的ID,通过ID可以区分每个流,解决了以前HTTP协议下每个请求独占连接的问题,解决相应的性能问题。
另一个优势就是我们多次提到的“背压”,其“背压”实现上实现了一种“租约机制”,响应者可以指定请求者在定义的时间范围内发送多少请求。
在负载均衡角度,RSocket可以实现客户端方式的负载均衡,实现方式依赖于LoadBalancedRSocketMono对象,在其中一组可用的RSocket实例中选择合适的RSocket实例进行访问。需要订阅LoadBalancedRSocketMono的onNext方法获取全部RSocket实例,同时对每个RSocket信息进行统计,计算每个实例负载以确定最佳选择。
在统计信息选择上包括:延迟,保持的连接数及未处理的请求数。这些运行时数据可以实时反应出来。
整个流上,通过keep-alive帧定期来回发送,探测连接的稳定性,keep-alive帧中还包含令牌,以确认请求者响应者最后的接收位置。
框架的支持
在Java体系下,对于RSocket的实现一般是基于TCP长链接实现的。不同于其他基于TCP协议的长链接的在于RSocket是一系列的协议规范。
在Spring5时代,Reactor和webflux是值得我们关注的一套技术,Reactor模型并不能提升请求性能,降低延迟,但是可以提升吞吐增强系统弹性。但是结合了RSocket后,对于http处理性能则如虎添翼。
之前的文章中讲过Reactor和WebFlux就不赘述了,RSocket和WebFlux结合的很好,可以很方便的使用Mono/Flux相关接口。
既然一直在提“背压”,那么“背压”在真实产品体验上有什么用呢?
如果有了基于应用程序协议上的“背压”实现,可以一定程度上减少APP上的无效或重复请求,一定程度上提升系统资源利用率。一些超级用户量产品的通信工程团队已经这样搞了,比如谷歌和FB。
当然国内阿里团队也将一部分精力投入到对于RSocket应用的普及上了,比如在Dubbo中就尝试了对RSocket的适配。
说了这么多,你是不是已经手痒痒了呢?打开SpringBoot2赶紧搞起来吧!
推荐阅读: