Netty笔记(三)之EventLoop与线程模型

netty版本

  1. netty版本:io.netty:netty-all:4.1.33.Final

EventLoop

  1. 一个EventLoop由一个永远不会改变的Thread驱动,同时任务可以提交给EventLoop实现,以立即执行或者调度执行。根据配置和CPU可用核心的不同,可能会创建多个EventLoop实例用以优化资源的使用,并且单个EventLoop可能会被指派用于服务多个Channel。事件和任务是以先进先出的顺序执行,这样可以保证字节内容总是按正确的顺序被处理,消除潜在的数据损坏的可能性
  2. 在Netty4中所有的I/O操作和事件都由已经被分配给了EventLoop的那个Thread来处理。
  3. Netty线程模型的卓越性能取决于对于当前执行的Thread的身份的确定(通过调用EventLoopinEventLoop(Thread)来实现),EventLoop将负责处理一个Channel的整个生命周期内的所有事件
  4. 如果当前调用的线程正是支撑EventLoop的线程,那么所提交的代码块将会被直接执行。否则EventLoop将调度该任务以便稍后执行,并将它放入到内部队列中。当EventLoop下次处理它的事件时,它会执行队列中的那些任务/事件。每个EventLoop都有它自己的任务队列,独立于任何其他的EventLoop
  5. 永远不要将一个长时间运行的任务放入到执行队列中,因为它将阻塞需要在同一个线程上执行的任何其他任务。如果必须要进行阻塞调用或者执行长时间运行的任务,建议使用一个专门的EventExecutor
  6. EventLoopChannelEventLoopGroup之间的关系
    • 一个EventLoopGroup包含一个或者多个EventLoop,EventLoop就是一个Channel执行实际工作的线程。
    • 一个EventLoop在它的声明周期内只和一个Thread绑定
    • 所有由EventLoop处理的I/O事件都将在它专有的Thread上被处理
    • 一个Channel在它的生命周期内只注册于一个EventLoop,在Netty I/O操作中,你的程序不需要同步,因为一个指定Channel的所有I/O始终由同一个线程来执行
    • 一个EventLoop可能会被分配给一个或多个Channel

异步传输

  1. 异步传输实现只使用了少量的EventLoop(以及和它们相关联的Thread),而且在当前的线程模型中,它们可能会被多个Channel所共享。这使得可以通过尽可能少量的Thread 来支撑大量的Channel,而不是每个Channel分配一个Thread
  2. EventLoopGroup负责为每个新创建的Channel分配一个EventLoop。 在当前实现中, 使用顺序循环( round-robin )的方式进行分配以获取一个均衡的分布,并且相同的 EventLoop可能会被分配给多个Channel。一旦一个Channel被分配给一个EventLoop,它将在它的整个生命周期中都使用这个EventLoop(以及相关联的 Thread)。所以不需要担心ChannelHandler的线程安全问题
  3. EventLoop的分配方式对ThreadLocal的使用的影响 。 因为一个EventLoop通常会被用于支撑多个Channel,所以对于所有相关联的Channel来说,ThreadLocal 都将是一样的。这使得它对于实现状态追踪等功能来说是个糟糕的选择。然而,在一些无状态的上下文中,它仍然可以被用于在多个Channel之间共享一些重度的或者代价昂贵的对象,甚至是事件。

阻塞传输

  1. 对于阻塞IO来说,每一个Channel都将被分配给一个EventLoop(以及它的 Thread)。保证每个Channel的I/O事件都将只会被一个Thread(用于支撑该 ChannelEventLoop的那个Thread)处理

Netty多线程最佳实践

  1. 服务端创建两个NioEventLoopGroup,用于隔离NIO AcceptorNIO I/O线程
  2. 尽量不要在ChannelHandler中启动用户线程(解码后用于将POJO消息派发到后端业务线程的除外)
  3. 解码要放在NIO线程调用的解码Handler中进行,不要切换到用户线程中完成消息解码
  4. 如果业务逻辑操作非常简单,没有复杂的业务逻辑计算,没有可能会导致线程被阻塞的磁盘操作、数据库操作、网络操作等,可以直接在NIO线程上完成业务逻辑编排,不需要切换到用户线程
  5. 如果业务逻辑处理复杂,不要在NIO线程上完成,建议将解码后的POJO消息封装成Task,派发到业务线程池中由业务线程执行,以保证NIO线程尽快释放,处理其他的I/O操作
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值