bio、nio、netty处理流程简析

本文只是说明流程,具体的代码网上可以找到,如果还没有跑过相关代码的,需要先找找相关资料了解。
Bio的处理流程如下图
bio、nio、netty处理流程简析_第1张图片
当一个客户端请求服务端建立连接后,服务端会单独为客户端生成一个线程处理io以及后续逻辑。如果客户端数量过大,就会使服务端超负荷。如果使用线程池,客户端数量过大,后面的客户端就有可能不能建立连接。
Nio的处理流程如下图
bio、nio、netty处理流程简析_第2张图片
服务端会先生成一个ServerSocketChannel,把他的Accept事件注册到一个selector上面,当有客户端连接服务端时,就会触发ServerSocketChannel的accept事件,用ServerSocketChannel的accept方法可以得到socketChannel,然后将socketChannel的read事件注册到selector上面,当客户端发送数据时,socketChannel就会触发read事件,读取socketChannel中的数据做后续处理。
此处的事件再多说几句。因为这个事件是由客户端发起的,有两个动作,一个是连接,一个是发送数据,不是很直观。可以跟js的的事件做一个类比,html代码里,submit,onclick就是一个定义好的事件,点击该button就会执行test方法中的代码,点击的动作就相当于连接或发送数据,跟nio中的事件非常类似。
Nio的服务端只有一个线程就能完成所有客户端的连接读取数据的操作。
Bio是同步阻塞,nio是同步非阻塞。所谓阻塞是指bio的方式,一个线程只能处理一个客户端,非阻塞是指nio的一个线程同时监听多个客户端。同步在bio中是指读取数据后在同一线程中处理后续逻辑,在nio中是指所有读取的数据都是在同一线程中处理后续逻辑。
Nio也可以做异步,那就是在读取数据后,将数据的处理当做一个任务放在一个线程池中,自己写这个代码会比较麻烦,有框架netty就是这个问题的完美解决方案。
Netty可以支持nio,还可以支持其他的,一般用nio,所以就以nio的功能举例,流程图如下:
bio、nio、netty处理流程简析_第3张图片
Netty服务器启动时,会生成两个线程组(也可以共用一个),一个线程组供ServerSocketChannel使用,称为group,一个线程组供SocketChannel使用,称为childgroup。ServerSocketChannel会被生成并注册Accept,当客户端连接时,会生成SocketChannel,同时在childgroup选择一个NioEventLoop也就是一个线程,将生成的SocketChannel注册到其中的selector。每个NioEventLoop维护的Selector是相互独立的。在childgroup中选择一个NioEventLoop时,是轮询的方式。也就是有多个客户端时,childgroup中的一个NioEventLoop会对应多个客户端,相对均匀分布。
本文只是把处理流程理了一遍,说一千道一万,不如源码看一看,有条件的建议看看netty源码。

你可能感兴趣的:(bio、nio、netty处理流程简析)