实现RPC框架(1) 编译码器和简易服务端和客户端

268 阅读2分钟

goRPC

这次没有使用Java去实现RPC框架,虽然Java的生态很完整,有netty框架等等,但是想要利用RPC框架提升自己go的工程能力;其次,go处理并发问题较Java更为方便,代码相对更加简洁

RPC框架

RPC是一种计算机通信协议,允许调用不同进程空间的程序。

不同应用程序之间的通信方式有很多,比如我们平时写crud项目经常用到的基于HTTP协议的Restful API。相比于RPC,Rest API标准统一,更通用,兼容性更好,支持不同种语言,可读性也很好。但是缺点也很多:

  • Restful需要额外定义,而RPC可以直接调用
  • 基于HTTP协议的Restful报文冗余,承载了过多的无效信息,而RPC通常都是自定义的
  • 相比于Restful,RPC很灵活,更容易扩展集成,比方说负载均衡,微服务的注册中心

在微服务和分布式系统中,客户端关心的是自己能否获取到结果,和服务端之间并不互相感知,服务端启动时将自己注册到注册中心,客户端调用时,从注册中心获取所有可用的实例,选择一个来调用。注册中心需要实现服务动态添加,删除,使用心跳确保服务处于可用状态等等

Part 1

Part1的github地址

消息的编码和译码

通常客户端发送的请求包括服务名,方法名,参数三个,服务端的响应包括错误error,返回值reply两个。我们将请求和响应中的参数和返回值抽象为body,剩余的信息存放到header

通信过程

HTTP报文分为headerbodybody的格式和长度通过header中的Content-TypeContent-Length决定,服务端通过解析header就能直到如何从body获取信息

RPC报文根据HTTP报文进行设计。为了提升性能,所以会压缩长度,一般在开头会规划固定字节,来协商相关信息

服务端实现

关键点是三个阶段:

  • readRequest
  • handleRequest
  • sendRequest

代码是并发处理请求的,但是回复请求如果并发回复会导致消息错乱,所以要使用lock

客户端实现

我们实现了一个消息的编译码器,并且客户端与服务端实现了简单的协议交换。同时实现了简易服务端,建立连接,读取,处理并回复客户端的请求