Netty网络模型
Netty是一个基于Java NIO的异步事件驱动网络应用程序框架。
基于NIO实现,简化了NIO繁琐的操作。如无需手动管理Selector,SelectionKey,Channel的注册,以及各种事件的判断。支持异步非阻塞,适合处理高并发的连接。
Netty使用的Reactor线程模型是主从Reactor多线程模式。Reactor设计模式也可以叫做反应者或者分发者模式。通过一个或者多个Reactor来监听或者分发客户端连接的IO事件并处理。
主从Reactor多线程模式
可以把主从Reactor看作是两个线程池(NioEventLoopGroup事件循环组),其中的每一个线程可以看作是一个NioEventLoop,即不断循环的执行处理任务的线程。每一个NioEventLoop都包含了两个部分:Selector和任务队列。我们知道在NIO中Selector是用于注册连接的通道的,也就是多个连接。可监听多个NioSocketChannel。
主Reactor
它的NioEventLoop维护了一个注册了NioServerSocketChannel的Selector。只负责监听并接收客户端的连接。它会轮询accept事件。
当有客户端发出连接请求时,接收连接,并分配一个NioSocketChannel,并将其交给从Reactor。
如果任务队列中有任务,就去执行任务。
从Reactor
接收到了主Reactor分配过来的连接后,会将连接分配给一个空闲的NioEventLoop线程。Netty会将此连接分配并注册到Selector维护的连接队列中并监听事件。
轮询read,write事件
监听到了事件,在对应的NioSocketChannel中处理此IO事件
如果任务队列中有任务,就去执行任务。
ChannelPipeline
管道,具体的业务处理的地方。在每一个NioSocketChannel中都有一个对应的ChannelPipeline,可以看作是一个双向处理器链表,用于处理入站和出站事件。由一系列ChannelHandler组成,每一个节点都是它的实例,可以自定义。当有事件发生的时候,Pipeline会将事件(数据)从链表头开始依次传递给每一个ChannelHandler进行处理。
入站和出站事件
真正具体处理的地方了。如数据的读操作,比如客户端给服务端发消息,服务端可以直接通过
自身入站事件的channelRead方法读取消息。出站就是数据写出站,比如服务端准备发送一个消息,如果有一个出站处理器,那么数据在发送之前会被此处理器拦截处理。
自定义Handler需要继承ChannelInboundHandlerAdapter,它提供了便捷的方法处理事件,只需要关注逻辑即可。
如:读,读完成,异常捕获。。。。
任务队列
任务队列通常执行一些IO外的异步/耗时任务。它不会阻塞当前的NioEventLoop线程。当执行完IO操作后,会去检查此队列是否有任务,有就通过任务执行器去执行。提交任务可以通过ctx.exector()或者ctx.channel.eventloop.execute()。自定义任务,定时任务都可以。
服务器端的启动配置
Netty是基于NIO的,封装很多的底层实现,可能就配置的时候所谓麻烦点,配置完之后只需要关注业务逻辑就可以了,客户端也是如此:
异步模型ChannelFuture
这个异步的结果体现在,执行某方法后,会立即返回这个异步Future对象,不会阻塞当前的线程。而这个Future对象则表示未来会产生的一个结果。跟webFlux中的异步对象Mono<type>差不多的道理。
这里则表示绑定服务器的未来结果是否成功。sync阻塞当前线程,直到绑定出结果。以确保服务端的正常运行。绑定的结果可以通过注册一个监听器回调来获取。