一次RPC调用过程:
1.客户端像调用本次对象一样,调用本地代理对象
2.代理对象将请求目标类名、方法名、参数等信息按照请求协议封装成Request
3.代理对象从服务治理平台拿到的服务端节点信息,与某一服务节点建立连接
4.代理对象将Request序列化字节数组,通过网络传输协议(一般是TCP)发送给服务端
5.服务端接收到请求,反序列化得到Request
6.服务端根据Request,找到对应实现,并完成计算,得到Response
7.服务端将Response序列化后发送给客户端
8.客户端收到服务端结果或错误提示
RPC框架描述:
1.服务提供者启动,并向注册中心注册服务节点
2.客户端启动,并从注册中心拉取最新服务节点
3.客户端与服务节点直接建立Socket通信,完成远程调用
4.服务节点发生变化,注册中心通知客户端,pull or push?
关于RPC Client:
1.服务节点列表,需在本地缓存,防止注册中心挂掉
如何更新缓存的服务节点数据?---定时拉取有效服务节点进行更新,方便负载均衡使用
2.客户端采取负载均衡策略,保证请求均衡地打到各个服务节点
如何进行负载均衡?---如果各节点权重相同,则随机选取一个节点;如果权重不同,则根据权重总和进行随机,看落到哪个分段
3.请求数据如何传输?
字节流传输(ByteArrayOutputStream)还是字符流传输(ObjectOutputStream)---
如何序列化为字节流-----Java自带序列化,Hessian,Protobuf---考虑序列化速度以及序列化后数据量大小
采用哪种IO模型发送和接收数据------BIO VS NIO
----BIO:Client需每次与Server进行三次握手,Server采用线程池应对,并发大了呢,QPS=1W?
----NIO:Client与Server保持长连接(Channel),Server端两个Channel,一个用于建立连接,一个用于IO
关于注册中心:
1.使用什么组件作为注册中心?----zk---为什么要用zk?
2.利用zk的什么节点?---永久节点-----zk不适合做服务注册发现?心跳机制
3.如何监听服务提供者节点变化,并及时周知到所有客户端?
----watcher模式
Mthrift做法: