博客
关于我
Netty源码解读
阅读量:789 次
发布时间:2023-02-15

本文共 2132 字,大约阅读时间需要 7 分钟。

Netty线程模型解读

Netty采用了独特的线程模型,主要包括BossGroup和WorkerGroup两个线程池。BossGroup负责接收客户端连接,而WorkerGroup则负责处理网络读写操作。这种设计使得Netty能够高效地管理多个连接和I/O操作。

Netty线程模型详解

  • 线程池结构

    • BossGroup:负责接收客户端的连接请求。
    • WorkerGroup:处理网络读写操作和业务逻辑。
  • 事件循环线程

    • 每个线程组(BossGroup和WorkerGroup)维护多个NioEventLoop。
    • 每个NioEventLoop管理一个Selector和一个TaskQueue。
  • Boss线程循环流程

    • 步骤1:处理连接事件(OP_ACCEPT),与客户端建立连接。
    • 步骤2:为新连接创建NioSocketChannel。
    • 步骤3:将NioSocketChannel注册到对应的Worker线程的Selector上。
    • 步骤4:运行TaskQueue中的任务。
  • Worker线程循环流程

    • 步骤1:轮询Selector上的所有NioSocketChannel的读写事件。
    • 步骤2:处理I/O事件(读写操作),并在对应的NioSocketChannel上执行业务逻辑。
    • 步骤3:运行TaskQueue中的任务,处理耗时业务。
    • 步骤4:通过pipeline管道处理数据,调用相应的handler处理器。
  • Netty服务启动示例

    // 创建线程组EventLoopGroup bossGroup = new NioEventLoopGroup(2);EventLoopGroup workerGroup = new NioEventLoopGroup(4);// 创建服务器启动对象ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bossGroup, workerGroup)        .channel(NioServerSocketChannel.class)        .option(ChannelOption.SO_BACKLOG, 1024)        .childHandler(new ChannelInitializer<>());// 启动服务器ChannelFuture cf = bootstrap.bind(9099).sync();

    Netty源码分析

    从bootstrap.bind作为入口分析Netty的启动流程,主要逻辑集中在以下三个步骤:

  • channelFactory.newChannel()

    • 创建NioServerSocketChannel实例,初始化感兴趣事件为OP_ACCEPT。
  • init(channel)

    • 初始化服务端pipeline,添加ChannelInitializer处理器。
  • register注册逻辑

    • 将NioServerSocketChannel注册到BossGroup的Selector上。
    • 处理连接事件时,设置非阻塞模式。
  • 服务端NioServerSocketChannel的注册逻辑

    public void register(EventLoop eventLoop, ChannelPromise promise) {    // 处理连接事件    eventLoop.execute(new Runnable() {        @Override        public void run() {            register0(promise);        }    });}private void register0(ChannelPromise promise) {    // 初始化服务端pipeline    pipeline.addLast(new ServerBootstrapAcceptor(...));    pipeline.fireChannelRegistered();    pipeline.fireChannelActive();}

    客户端连接处理流程

  • 服务端接收连接请求并创建NioSocketChannel。
  • 将NioSocketChannel注册到WorkerGroup的Selector上,设置OP_READ事件。
  • 客户端通过pipeline执行读写操作,调用自定义handler处理逻辑。
  • 数据读写处理

    public void read() {    // 读取数据并调用pipeline中的handler    pipeline.fireChannelRead(...);}protected abstract int doReadMessages(List buf) {    // 创建NioSocketChannel并注册    buf.add(new NioSocketChannel(...));    return 1;}

    通过以上流程可以清晰地看到Netty如何高效地管理客户端连接和数据读写,确保服务的稳定性和性能。

    转载地址:http://ovcfk.baihongyu.com/

    你可能感兴趣的文章