RPC中的一些问题
1.数据协议
序列化的方式(数据包的大小、序列化的优化)
要支持更多的数据形式(xml,json等等)
---->自定义数据的协议头,自定义数据的结束。
2.IO模型
2.1常见的IO模型
----->同步阻塞IO(Blocking IO):传统的IO模型
----->同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,
非阻塞的IO要求socket被设置为NONBLOCK.这里所说的NIO不是java不是java的NIO库(new io)
----->IO多路复用(IO Multiplexing):Reactor设计模式 也称为异步阻塞IO。
java中的Selector和linux中的epoll都是这种模式
----->异步IO(Asynchronous IO) :Proactor设计模式 异步非阻塞IO。
2.2同步和异步 : 用户线程和内核的交互方式
---->同步是指用户线程发起IO请求后,需要等待或者轮询你IO操作完成后才能继续执行
---->异步是指用户线程发起IO请求后,继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册回调函数
2.3阻塞和非阻塞
用户线程调用内核IO操作的方式,阻塞是指IO操作需要彻底完成后才能返回到用户空间,
非阻塞是指IO操作被调用后立即返回用户一个状态,无需等到IO操作彻底完成后
2.4 同步阻塞IO
用户线程通过系统调用read发起IO操作,由用户空间转换到内核空间,
内核等待数据包达到后,然后将接收到的数据拷贝到用户空间,完成read操作
伪代码:{
read(socket,buffer);
process(buffer)
}
用户需要等待read将socket中的数据读取到buffer后,才能继续处理接收的数据,
整个IO请求的过程中,用户线程是被苏泽的,导致用户在发起IO请求时,不能做
任何事情,对CPU利用不够。
2.5同步非阻塞IO
在同步阻塞IO的基础上将Socket设置NONBLOCK。这样做用户线程可以在发起IO请求后立即返回.
用户线程需要不断的发起IO请求,直到数据达到后,才能真正读取到数据,继续执行
伪代码:{
while(read(socket,buffer)!=SUCCESS){
process(buffer);
}
}
户线程可以在发起IO请求后立即返回.但是为了得到数据,仍需要不断轮询,重复请求,
消耗了大量的CPU资源。很少直接使用这种模型
2.6 多路复用IO
IO多路复用建立在内核提供的多路分离函数select基础之上的,使用select
函数可以避免同步非阻塞IO模型中的轮询等待问题。
用户首先将需要进行的IO操作的socket添加到select中,然后阻塞等待select系统调用返回。
当数据达到时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并
继续执行 看起来比同步阻塞模型效率更差。但是,使用select以后最大的优势是用户可以
在一个线程内同时处理多个socket的io请求,用户可以注册同个socket,然后不断调用select
读取被激活的socket.达到同一个线程内同时处理多个IO请求
伪代码{
select(socket);
while(1){
sockets = select();
for(Socket socket : sockets){
if(can_read(socket)){
read(socket,buffer);
process(buffer);
}
}
}
}
IO多路复用模型使用了Reactor设计模式实现了这一机制
2.7 异步IO
“真正“的异步IO需要操作系统更强的支持.
异步IO模型中,当用户线程收到通知时,数据已经被内核读取完毕,并放在了用户线程
指定的缓存区内,内核在IO完成后通知用户线程直接使用即可。
操作系统支持并非特别完善,更多采用的是IO多路复用模拟异步IO方式
3.线程模型
rpc异步调用 实现
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Dubbo异步调用实现
具体原理和介绍参看dubbo官方文档:http://dubbo.apache.org/zh-cn/
dubbo 异步调用 html api接口