详细图解 Netty Reactor 启动全流程 | 万字长文 | 多图预警 ...

打印 上一主题 下一主题

主题 1945|帖子 1945|积分 5835

本系列Netty源码解析文章基于 4.1.56.Final版本

大家第一眼看到这幅流程图,是不是脑瓜子嗡嗡的呢?

大家先不要惊慌,问题不大,本文笔者的目的就是要让大家清晰的理解这幅流程图,从而深刻的理解Netty Reactor的启动全流程,包括其中涉及到的各种代码设计实现细节。

在上篇文章《聊聊Netty那些事儿之Reactor在Netty中的实现(创建篇)》中我们详细介绍了Netty服务端核心引擎组件主从Reactor组模型 NioEventLoopGroup以及Reactor模型 NioEventLoop的创建过程。最终我们得到了netty Reactor模型的运行骨架如下:

现在Netty服务端程序的骨架是搭建好了,本文我们就基于这个骨架来深入剖析下Netty服务端的启动过程。
我们继续回到上篇文章提到的Netty服务端代码模板中,在创建完主从Reactor线程组:bossGroup,workerGroup后,接下来就开始配置Netty服务端的启动辅助类ServerBootstrap 了。
  1. public final class EchoServer {
  2.     static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
  3.     public static void main(String[] args) throws Exception {
  4.         // Configure the server.
  5.         //创建主从Reactor线程组
  6.         EventLoopGroup bossGroup = new NioEventLoopGroup(1);
  7.         EventLoopGroup workerGroup = new NioEventLoopGroup();
  8.         final EchoServerHandler serverHandler = new EchoServerHandler();
  9.         try {
  10.             ServerBootstrap b = new ServerBootstrap();
  11.             b.group(bossGroup, workerGroup)//配置主从Reactor
  12.              .channel(NioServerSocketChannel.class)//配置主Reactor中的channel类型
  13.              .option(ChannelOption.SO_BACKLOG, 100)//设置主Reactor中channel的option选项
  14.              .handler(new LoggingHandler(LogLevel.INFO))//设置主Reactor中Channel->pipline->handler
  15.              .childHandler(new ChannelInitializer<SocketChannel>() {//设置从Reactor中注册channel的pipeline
  16.                  @Override
  17.                  public void initChannel(SocketChannel ch) throws Exception {
  18.                      ChannelPipeline p = ch.pipeline();
  19.                      //p.addLast(new LoggingHandler(LogLevel.INFO));
  20.                      p.addLast(serverHandler);
  21.                  }
  22.              });
  23.             // Start the server. 绑定端口启动服务,开始监听accept事件
  24.             ChannelFuture f = b.bind(PORT).sync();
  25.             // Wait until the server socket is closed.
  26.             f.channel().closeFuture().sync();
  27.         } finally {
  28.             // Shut down all event loops to terminate all threads.
  29.             bossGroup.shutdownGracefully();
  30.             workerGroup.shutdownGracefully();
  31.         }
  32.     }
  33. }
复制代码
在上篇文章中我们对代码模板中涉及到ServerBootstrap 的一些配置方法做了简单的介绍,大家如果忘记的话,可以在返回去回顾一下。
ServerBootstrap类其实没有什么特别的逻辑,主要是对Netty启动过程中需要用到的一些核心信息进行配置管理,比如:


  • Netty的核心引擎组件主从Reactor线程组: bossGroup,workerGroup。通过ServerBootstrap#group方法配置。
  • Netty服务端使用到的Channel类型:NioServerSocketChannel ,通过ServerBootstrap#channel方法配置。
    以及配置NioServerSocketChannel时用到的SocketOption。SocketOption用于设置底层JDK NIO Socket的一些选项。通过ServerBootstrap#option方法进行配置。
主ReactorGroup中的MainReactor管理的Channel类型为NioServerSocketChannel,如图所示主要用来监听端口,接收客户端连接,为客户端创建初始化NioSocketChannel,然后采用round-robin轮询的方式从图中从ReactorGroup中选择一个SubReactor与该客户端NioSocketChannel进行绑定。
从ReactorGroup中的SubReactor管理的Channel类型为NioSocketChannel,它是netty中定义客户端连接的一个模型,每个连接对应一个。如图所示SubReactor负责监听处理绑定在其上的所有NioSocketChannel上的IO事件。


  • 保存服务端NioServerSocketChannel和客户端NioSocketChannel对应pipeline中指定的ChannelHandler。用于后续Channel向Reactor注册成功之后,初始化Channel里的pipeline。
不管是服务端用到的NioServerSocketChannel还是客户端用到的NioSocketChannel,每个Channel实例都会有一个Pipeline,Pipeline中有多个ChannelHandler用于编排处理对应Channel上感兴趣的IO事件。
ServerBootstrap结构中包含了netty服务端程序启动的所有配置信息,在我们介绍启动流程之前,先来看下ServerBootstrap的源码结构:
ServerBootstrap


ServerBootstrap的继承结构比较简单,继承层次的职责分工也比较明确。
ServerBootstrap主要负责对主从Reactor线程组相关的配置进行管理,其中带child前缀的配置方法是对从Reactor线程组的相关配置管理。从Reactor线程组中的Sub Reactor负责管理的客户端NioSocketChannel相关配置存储在ServerBootstrap结构中。
父类AbstractBootstrap则是主要负责对主Reactor线程组相关的配置进行管理,以及主Reactor线程组中的Main Reactor负责处理的服务端ServerSocketChannel相关的配置管理。
1. 配置主从Reactor线程组
  1. ServerBootstrap b = new ServerBootstrap();
  2. b.group(bossGroup, workerGroup)//配置主从Reactor
复制代码
  1. public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel> {
  2.      //Main Reactor线程组
  3.     volatile EventLoopGroup group;
  4.     //Sub Reactor线程组
  5.     private volatile EventLoopGroup childGroup;
  6.     public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
  7.         //父类管理主Reactor线程组
  8.         super.group(parentGroup);
  9.         if (this.childGroup != null) {
  10.             throw new IllegalStateException("childGroup set already");
  11.         }
  12.         this.childGroup = ObjectUtil.checkNotNull(childGroup, "childGroup");
  13.         return this;
  14.     }
  15. }
复制代码
2. 配置服务端ServerSocketChannel
  1. ServerBootstrap b = new ServerBootstrap();
  2. b.channel(NioServerSocketChannel.class);
复制代码
[code]public class ServerBootstrap extends AbstractBootstrap {    //用于创建ServerSocketChannel  ReflectiveChannelFactory    private volatile ChannelFactory, Object> options = new LinkedHashMap, Object> childOptions = new LinkedHashMap, Object>[] currentChildOptions;        synchronized (childOptions) {            currentChildOptions = childOptions.entrySet().toArray(EMPTY_OPTION_ARRAY);        }        final Entry

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

罪恶克星

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表