带你读《Apache Tomcat的云原生演进》——Dubbo Echo System-Dubbo Go Pixiu(1)https://developer.aliyun.com/article/1377517
2. Pixiu的多协议转换
Pixiu作为专注于Dubbo的代理,主要支持以下四种协议:
∙ HTTP,它是Pixiu对外暴露服务的主要形式。
∙ Dubbo 2,它的协议是基于TCP传输层协议之上构建的一套RPC通信协议,由于其紧凑、灵活、高性能的特点,在Dubbo2时代取得了非常广泛的应用。
∙ Triple,它是Dubbo3发布的面向云原生时代的通信协议,它基于HTTP/2并且完全兼容gRPC协议,原生支持Streaming通信语义。
∙ Triple PB,自 Triple 协议开始,Dubbo 还支持基于 Protocol Buffers 的服务定义与数据传输。
在没有Pixiu之前,Dubbo 2已经实现了一个叫泛化调用的功能。比如对于Dubbo 2来说,如果没有服务定义,依旧可以作为一个Client发起请求,我们把这个称之为泛化调用。
这个泛化调用会构建一个泛化专用的Service,在第一次发起请求的时候会有一个懒加载的过程,即在注册中心拉取对应服务的元数据,这一步的耗时会比较久。然后还要进行序列化、发送请求、接收响应,到这就完成了。
泛化调用可以在一定程度上,让你在没有服务定义的情况下调用Dubbo,但它还不够完善。因此Pixiu在第第一实现的Http2Dubbo的功能中,对这个功能做了增强。
首先我们对泛化的Service做了连接,然后Adpter模块会提前把对应服务元数据拉取出来,这样首次调用的时延就没有了。最后也是最重要的,Dubbo的调用无法对外,而Pixiu可以做到以Http的形式把这个服务暴露出去,并且能够通过Filter增加丰富的能力。
代理Triple协议并不像Dubbo协议那么简单,因为Dubbo2采用的序列化hession协议本身是紧凑的,但它其中的信息并没有丢失。而Triple协议使用的proto序列化就不一样,为了极致的性能,它把报文中的字段全部抹掉了,这也导致了如果你想要反序列化,就必须拿到原始的ID 2的定义,否则是解析不出来的。
对于这个情况,Pixiu用到grpc的reflection功能。在Pixiu发起调用之前,会去对应的上游服务请求下载对应proto元数据。这样Pixiu就可以正确把这个数据序列化给到上游,同样接收响应反序列化。
这里有一个小故事,去年阿里云有一个想把K8s的API对外暴露出去的需求,因此就找到了我们,想要借助Http2Dubbo的功能,把API暴露出去。但在实操的过程中发现了一些问题,K8s的API是用Gogoproto组件编译出来的,而grpc reflection由于一些原因并不支持,所以为了支持这种形式的代理,我们用提前引入了proto文件的形式,让这个需求得以完成。
刚才有提到Http2Dubbo,也有提到Http2Triple,但它们都是7层代理协议。在4层我们做了Pixiu的Listener监听一个Dubbo协议,然后一个Dubbo请求过来,调用到Pixiu,Pixiu是可以把这个请求转换成Triple协议调用出去的。同样Pixiu去监听一个Triple协议,也可以调用到Dubbo。这几种协议之间是可以互相转换的,这个就是Pixiu的多协议转换。
带你读《Apache Tomcat的云原生演进》——Dubbo Echo System-Dubbo Go Pixiu(3)https://developer.aliyun.com/article/1377515