怎么实现一个RPC框架?

角色
1)服务消费者
2)服务提供者

基础设施
1)远程代理(jdk/cglib)
2)序列化与反序列化(协议格式与序列化方法)
3)网络传输(TCP/UDP)

服务消费者
1)连接管理

TCP长连接,维护一个类似数据库连接池一样的连接池,
每次调用都拿出一条连接,发送数据,可以多个线程
共用一条TCP连接,客户端调用后阻塞在某地方,
数据回来根据会话ID唤醒对应线程,可以Map+CounDownLatch实现

2)负载均衡

随机
轮询
取模
权重随机
权重轮询
一致性hash

3)超时处理

客户端调用服务端后,阻塞一定时间,超时自动唤醒抛出异常,比如
CountDownLatch#await(long timeout, TimeUnit unit)
方法可以实现
1
2
3
4)调用方式

同步阻塞
异步(注册回调函数)
单向

服务提供者
1)IO线程模型

IO模型
BIO/NIO/AIO

IO线程模型

BIO:
BIO单线程
BIO+线程池

NIO
单Reactor单线程
单Reactor多线程
主从Reatcor多线程
2)超时丢弃

要实现这个功能,必须IO线程读取请求数据包后
封装成Task放到队列,Task包含创建时间,线程
从队列获取任务后,先判断当前任务是否已经过期,
如果过期,直接丢弃

如果还有其他的实现,可以留言交流

3)优雅关闭

目的:
进程退出前确保接收到的请求全部处理完成,不考虑机器断电等情况

通知调用方自己要关闭
处理完所有队列的任务

怎么通知调用方?
返回数据中带关闭信息;
专门关闭协议通知调用方;

服务端预留关闭接口,可以开启秘密的TCP端口
每次处理请求之前要经过一系列的过滤器,判断
当前服务是否已经关闭/重启状态,如果是,
处理完成请求后返回服务状态信息

也可以服务端主动通知消费端,消费端要预留调用的接口

4)过载保护

刚才说到IO线程会读取请求数据,封装成Task放到队列,
队列可以设置最大数量,超过了就不能再放任务

上一篇:Dubbo+Zookeeper创建服务提供者与消费者


下一篇:RPC