总结自:你应该知道的RPC原理
一、如何调用他人的远程服务:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
二、怎样对消息进行编码和解析
1、消息数据结构
request:
1.接口名称
2.方法名称
3.参数类型&参数值
4.超时时间
5.requestID
response:
1.返回值
2.状态code
3.requestID
2、序列化和反序列化
序列化:将数据结构或对象转换成二进制串的过程,也就是编码的过程。
反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。
为什么序列化:转换为二进制串后才好进行网络传输。
为什么需要反序列化:将二进制转换为对象才好进行后续处理。
3、通信
具体可以学习:一个故事讲清楚NIO
BIO:每次来一个请求,就分配到线程池中由一个线程处理,如果超出了线程池的最大上限(10个),就扔到队列等待 。
NIO:典型NIO有三类线程,分别是mainReactor线程、subReactor线程、work线程。不同的线程干专业的事情,最终每个线程都没空着,系统的吞吐量自然就上去了。mainReactor线程负责监听server socket,accept新连接,并将建立的socket分派给subReactor;subReactor可以是一个线程,也可以是线程池(一般可以设置为CPU核数),负责多路分离已连接的socket,读写网络数据,这里的读写网络数据可类比顾客填表这一耗时动作,对具体的业务处理功能,其扔给worker线程池完成。
异步方式:让线程尽可能处于不空闲的状态下。
总结:“分而治之,将任务拆分开来,由专门的人负责专门的任务。”
4、消息里为什么要有requestID?
服务端处理实际上需要时间,采用异步方式能够释放当前线程,让线程往后执行,等服务端处理完成后将结果以消息形式发送给客户端。