Netty学习总结之EventLoop

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013560667/article/details/87880896

我们都知道Netty是一个通信框架,而且是一个高效的通信框架,通过异步事件驱动模型,使用很少的资源就可以实现较高的并发,并且维持较好的效率完成通信,那么我们就不得不说一下Netty的线程模型,为什么Netty能通过少量的线程就可以实现较高的并发量。这里我们不得不说一下Netty的EventLoop,Netty的一个EventLoop其实和一个特定的线程绑定, 并且在其生命周期内, 绑定的线程都不会再改,就是从你声明EventLoopGroup时指定EventLoop数量时就已经定义好了,系统会根据定义生成好对应的线程,且该线程的生命周期同服务器的声明周期。Netty就是采用多路复用IO进行事件监听,另外,使用不同的线程分别处理客户端的连接、数据读写。整个处理结构如下图,简单说明下:

  • Boss EventLoopGroup主要处理客户端的connect事件,包含多个EventLoop,每个EventLoop一个线程;
  • Worker EventLoopGroup主要处理客户端Socket的数据read、write事件,包含多个EventLoop,每个EventLoop一个线程;
  • 无论是Boss还是Worker,事件的处理都是通过Channel Pipleline组织的,它是责任链模式的实现,包含一个或多个Handler;
  • 侦听一个端口,只会绑定到Boss EventLoopGroup中的一个Eventloop;
  • Worker EventLoopGroup中的一个Eventloop,可以监听多个客户端Socket;

EventLoop肩负着两种任务:

  • 第一个是作为 IO 线程, 执行与 Channel 相关的 IO 操作, 包括 调用select等待就绪的IO事件、读写数据与数据的处理等;
  • 第二个任务是作为任务队列, 执行 taskQueue 中的任务, 例如用户调用eventLoop.schedule提交的定时任务也是这个线程执行的;

现在我们来说一下第一个任务,第一个任务主要是分成两部分,一部分是server端,server端的Boss EventLoop主要负责处理处理客户端的链接,以及将建立链接的客户端交接给worker EventLoop,通过worker来处理具体的业务逻辑,然后将业务逻辑返回给客户端。另一部分客户端呢,他不需要监听链接,他只需要worker EventLoop与服务端建立链接,写数据到IO,然后负责接收服务器返回的信息。

第一个任务比较好理解,主要解释下第二个:从socket数据到数据处理,再到写入响应数据,Netty都在一个线程中处理,主要是为了线程安全考虑,减少竞争和线程切换,通过任务队列的方式,可以在用户线程提交处理逻辑,在Eventloop中执行。

整个EventLoop干的事情就是select -> processIO -> runAllTask,processIO处理IO事件相关的逻辑,runAllTask处理任务队列中的任务,如果执行的任务过多,会影响IO事件的处理,所以会限制任务处理的时间。

需要注意的是,不建议在 ChannelHandler 中直接实现耗时或阻塞的操作,因为这可能会阻塞 Netty 工作线程,就是IO读写会被阻塞,会直接导致性能下降,严重会导致 Netty 无法及时响应 IO 处理,所以我们需要使用业务线程来处理耗时的业务。

猜你喜欢

转载自blog.csdn.net/u013560667/article/details/87880896