个人理解,可以把EventLoop看作一个线程,而EventLoopGroup就是一个线程池。 EventLoop 定义了 Netty 的核心抽象,用于处理连接的生命周期中所发生的事件。Channel、EventLoop、Thread 以及 EventLoopGroup 之间的关系如下图所示:
EventLoopGroup通过负载均衡算法选择某个EventLoop去绑定Channel。
EventLoop通过其Selector选择器(类似epoll)去监听其绑定的Channel上发生的事件,并根据事件类型的不同,交给相应的ChannelHandler处理。
在Netty的线程模型为基于事件驱动的 Reactor 模型,可以通过配置实现几种不同类型的Reactor模型,如 单线程模型、多线程模型和主从线程模型等。因此可能用到数量不同的EventLoopGroup线程池,如主从线程模型就会用到两个EventLoopGroup,一个用于监听从客户端发来的连接,一个用于读写数据、处理业务等。
在web Server中:主线程调用epoll_wait等待客户端的连接,对于新到的连接调用accept系统调用生成一个用于通信的socket文件描述符,并把这个文件描述符与一个类似Channel的http连接对象(自己封装的一个类)进行绑定,然后注册进epoll。
当有网络中有数据到达这个用于通信的socket文件描述符的读缓冲区,或服务器已经正确生成response并注册了写就绪事件时,epoll会将这个文件描述符拿出,交给一个工作线程执行相应的操作。由于工作线程与主线程共用一个epoll,因此一个工作线程也只能处理一个连接。
在Netty中:如果使用主从线程模型,此时需要两个EventLoopGroup,第一组将只包含一个 ServerChannel,代表服务器自身的已绑定到某个本地端口的正在监听的套接字。而第二组将包含所有已创建的用来处理传入客户端连接(对于每个服务器已经接受的连接都有一个)的 Channel(类似用于通信的socket文件描述符),如下图所示。
与 ServerChannel 相关联的 EventLoopGroup 将分配一个负责为传入的连接创建Channel 的EventLoop。一旦连接被接受,第二个EventLoopGroup 就会给它的 Channel分配一个 EventLoop。
与WebServer项目不同的是,在该线程模型中,Netty中每个工作线程EventLoop都有自己的Selector(可理解为epoll),因此一个EventLoop可以处理多个Channel。
当ChannelHandler被添加到ChannelPipeline时,它将会被分配一个ChannelHandlerContext。通过使用作为参数传递到每个方法的 ChannelHandlerContext,事件可以被传递给当前ChannelHandler链中的下一个 ChannelHandler。因为你有时会忽略那些不感兴趣的事件,所以 Netty提供了抽象基类ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapters。通过调用 ChannelHandlerContext 上的对应方法,每个都提供了简单地将事件传递给下一个ChannelHandler的方法的实现。随后,你可以通过重写你所感兴趣的那些方法来扩展这些类。具体实例会在后面给出。
个人理解:可以将ChannelHandlerContext类比为Linux中的socket文件描述符。在Netty框架中,ChannelHandlerContext是一个上下文对象,用于表示一个通道的上下文信息,包括该通道的事件处理器、通道的配置信息以及与该通道相关的一些状态信息。类似于Linux中的socket文件描述符,它可以用于发送和接收数据,以及进行其他与通道相关的操作。但是需要注意的是,ChannelHandlerContext并不是一个操作系统底层的文件描述符,而是Netty框架中的一个抽象概念。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |