您的位置:首页 > 其它

RPC中nio和代理模式的应用

2017-11-14 19:43 183 查看
RPC
NIO和代理模式在rpc中的应用
一、NIO
Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API
Channels and Buffers (通道和缓冲区):
标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中,Channel同时支持读和写。
Asynchronous IO(异步IO):
Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。
Selectors(选择器):
Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。
此处引用网友通俗的比喻:

Channel对应以前的流,Buffer不是什么新东西,Selector是因为nio可以使用异步的非堵塞模式才加入的东西。以前的流总是堵塞的,一个线程只要对它进行操作,其它操作就会被堵塞,也就相当于水管没有阀门,你伸手接水的时候,不管水到了没有,你就都只能耗在接水(流)上。nio的Channel的加入,相当于增加了水龙头(有阀门),虽然一个时刻也只能接一个水管的水,但依赖轮换策略,在水量不大的时候,各个水管里流出来的水,都可以得到妥善接纳,这个关键之处就是增加了一个接水工,也就是Selector,他负责协调,也就是看哪根水管有水了的话,在当前水管的水接到一定程度的时候,就切换一下:临时关上当前水龙头,试着打开另一个水龙头(看看有没有水)。当其他人需要用水的时候,不是直接去接水,而是事前提了一个水桶给接水工,这个水桶就是Buffer。也就是,其他人虽然也可能要等,但不会在现场等,而是回家等,可以做其它事去,水接满了,接水工会通知他们。这其实也是非常接近当前社会分工细化的现实,也是统分利用现有资源达到并发效果的一种很经济的手段,而不是动不动就来个并行处理,虽然那样是最简单的,但也是最浪费资源的方式。

1.1 NIO服务端开发步骤
1)创建ServerSocketChannel,配置它为非阻塞。
2)绑定监听,配置TCP参数,例如 backlog大小
3)创建一个独立的IO线程,用于轮询多路复用器Selector
4)创建Selector,将之前创建的ServerSocketChannel注册到Selector上,监听SelectionKey.Accept
5)启动IO线程,在循环体内执行Selector.select,轮询就绪的通道Channel
6)当轮询到处于就绪状态的Channel,需要对其进行判断,如果是OP_ACCEPT状态,说明是新的客户端接入,则调用新的客户端接入,则调用ServerSocketChannel.accept()方法接受新的客户端
7)设置新接入的客户端链路SocketChannel为非阻塞模式,配置其他的一些TCP参数
8)将SocketChannel注册到Selector,监听OP_READ操作位
9)如果轮询的Channel为OP_READ,则说明SocketChannel中有新的就绪的数据包需要读取,则构造ByteBuffer对象,读取数据包
10)如果轮询的Channel为OP_WRITE,说明还有数据没有发送完成,需要继续发送。
部分源码
//主要标志位码
public static final int OP_READ = 1 << 0;
public static final int OP_WRITE = 1 << 2;
public static final int OP_CONNECT = 1 << 3;
public static final int OP_ACCEPT = 1 << 4;
//返回有效数据的长度
public final int remaining() {
return limit - position;
}
//判断是否有有效数据
public final boolean hasRemaining() {
return position < limit;
}
//返回有效数据范围
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}

1.2 NIO编程优点
1>客户端发起的连接操作异步,在通过多路复用器注册 OP_CONNECT等待后续结果,不会被同步阻塞
2>SocketChannel的读写操作都是异步的,没有可读写的数据他不会同步等待,直接返回,这样IO通信线程可以处理其他链路,不需要同步等待这个链路是否可用

3> 线程模型优化,JDK的 Selector通过epoll实现,没有句柄数的限制,性能不会随着客户端的增加而线性下降。非常适合高负载和高性能的网络服务器。

二、关于代理模式请自行查看代理模式---动态代理

            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: