Jump to Navigation

gRPC半透明转发反向代理

gRPC半透明转发反向代理

转发需求说明

基于gRPC协议的网络服务代理层,能够起到正确转发请求的功能。

在真实运行环境情况中,服务可能表现的更离散,通过添加一个带路由功能的、行为一致的反向代理层, 有效减小客户端要考虑的不同处理机制,同时也简化了客户端的一些配置。

特性: * 半透明转发(相对于透明转发) * 自发现路由(相对于固定路由) * 多协议支持 * 协议不变规则 * 对等无状态

半透明转发

透明转发,指的是在转发TCP连接上,逐字节无修改的转发。这种转发适合后端一致,只开放一个出口的场景。

在该模块使用的半透明指的是需要对请求进行部分解析,解析出来请求的服务名称/路径信息,根据这一信息转发到合适后端。

请求包包含两个部分,对目前支持的协议来说,一个是头信息部分,一个是数据部分。

注意,这里的部分解析,只解析头信息部分,并不解析数据部分,因为gRPC协议的解析需要数据包相应的结构体, 而在代理层选择不带数据包的结构体,也就无法解析数据包了。这些数据包,只需要透明原样转发到后端即可。

对于部分解析的请求,确定转发后端后,重新构造新的请求,并发送到后端。

一般情况下,新构造的请求包,可能与原包在字节码一级上不一致,比如ip部分不一致,或者头信息有变化, 但是必须要保证不能影响请求的响应的结果,以及要考虑转发前后请求所在连接的行为, 比如连接行为的一致性问题,一端关闭连接则两端都关闭,或者维护后端连接池。

该模块的当前实现中,使用了转发前后连接一致行为方式,即到转发后端的连接的打开和关闭与客户端行为一致。 但也可能为了优化做转发连接的缓存相关机制来提高一些程序运行效率。

当代理接收到后端的响应,要考虑的更少一些,基本上可以直接把整个请求包响应给客户端了。

自发现路由

自动发现,指的是根据请求信息定位服务所在节点的机制,在这之前的文档已经有涉及,不再详述。

这里提一下该自发现路由机制,实现上是采用了微服务中的服务端发现机制的概念。

并且与上一节中讲的对外服务的一致性开放接口问题有关,在非一致性开放接口的基础之后, 添加一层一致性接口,让离散的服务重新维护起来,不影响服务实现的复杂度,并且能够简化客户端的调用。

当然架构的灵活性、自动化、与多层次模式会带来一定的时间损失,可以在不同的场景调整软件的部署架构。

多协议支持

该子模块目前支持常用协议gRPC和http/1.x。

并且还要说明的一点,目前的实现中,协议与通信包格式是绑定的,比如gRPC使用protobuf3包格式,http/1.x使用json协议。

还是不展望太多了。

协议不变规则

该模块中对于所支持的协议,采用不改变协议的方式转发到后端,比如gRPC转发时依然使用gRPC请求, http/1.x转发时依然使用http/1.x。

采用这一机制主要在于gRPC协议使用了protobuf3强类型序列化,在go的实现中,如果要解析这部分序列化数据包的话, 则需要加载后端所有服务的对应的protobuf3结构体。这种代码的强类型传播,让该代理模块依赖太多, 需要在每一个后端服务有接口改变时重新编译并重启才能生效,目前认为这种依赖传播不值得去支持。

还有一些序列化方式,为了效率和接口的可靠性,用强类型传播达到这一目标,也适用目前的考虑。

所以暂时选用了转发不变协议了这种策略,这样代理也比较轻量一些。

一点讨论

前面讨论的是根据头信息与服务发现机制决定转发后端,其实在简化的情况下,这个模块可以当做一个简单的固定gRPC协议来使用。

如果单独从网络协议的角度,几乎每种协议都有对应的反向代理功能。 那么该模块的作用是不是重复了呢? 应该是有重复的功能,但侧重点不同,该模块重点更多在于协助开发的,把本来集成的开发的项目中的模块独立成单独的模块而已。

代码
coming soon...
Category:

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.


Main menu 2

Story | by Dr. Radut