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
消息的编码和译码
通常客户端发送的请求包括服务名,方法名,参数三个,服务端的响应包括错误error,返回值reply两个。我们将请求和响应中的参数和返回值抽象为body,剩余的信息存放到header
通信过程
HTTP报文分为header和body,body的格式和长度通过header中的Content-Type和Content-Length决定,服务端通过解析header就能直到如何从body获取信息
RPC报文根据HTTP报文进行设计。为了提升性能,所以会压缩长度,一般在开头会规划固定字节,来协商相关信息
服务端实现
关键点是三个阶段:
- readRequest
- handleRequest
- sendRequest
代码是并发处理请求的,但是回复请求如果并发回复会导致消息错乱,所以要使用lock
客户端实现
我们实现了一个消息的编译码器,并且客户端与服务端实现了简单的协议交换。同时实现了简易服务端,建立连接,读取,处理并回复客户端的请求