实现RPC远程调用通信框架整体需要解决四个问题:
- 通信的框架
- 客户端和服务端如何建立网络连接?
- 服务端如何处理请求?
- 数据传输需要采用什么协议?
- 数据如何序列化和反序列化?
但是实现RPC调用还需要解决
- 服务描述,即数据构造成的样子
1.客户端和服务端如何建立网络连接
现在的通信一般都是基于TCP协议简历的网络连接。
- HTTP通信,默认使用HTTP协议
- Socket 通信
2.服务端如何处理请求?
BIO(同步阻塞方式)
每个请求都需要新开线程去处理,如果达到os最大的线程数瓶颈,新来的请求没有办法处理
- 适合连接数少
NIO(同步非阻塞方式),服务器端优化
通过I/O多路复用技术,单线程的情况下可以同时处理多个客户端请求,这种开销小,节省os开销。
- 适合连接数多,请求耗时比较轻的业务场景
AIO(异步非阻塞方式),客户端优化
客户端只需要发起一个I/O操作然后立即返回,等I/O操作真正完成之后,客户端会得到I/O操作完成的通知,此时客户端只需要对数据进行处理就好了,不需要进行实际的I/O读写操作,真正的I/O读写操作已经由内核完成,这种方式的优势客户端无需等待,不存在阻塞等待问题。
- 适合连接数多,请求耗时比较重的业务场景
3.数据传输需要采用什么协议?
因为现在的通信都是基于TCP协议,但是TCP是面向字节流的,无边界。所以会产生粘包和半包问题,具体可以查看点击
除了公有协议的Http协议等,现在更多的RPC框架都自定义私有协议。
- 协议重点就是:协议头里需要包含数据包的字节数
4.数据该如何序列化和反序列化?
字节数组<->java Object
如何选择,考虑维度?
- 空间大小(根据数据量变)
- 编解码速度(根据数据量变)
- 可读性
- 多语言支持
现在最火的就是json和pb。
案例
- 下面就有一个实现的RPC远程调用的实现