博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty(四)——线程模型
阅读量:6891 次
发布时间:2019-06-27

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

hot3.png

3.x 线程模型

    

In:

  • Work线程将消息从TCP缓冲区读取到SocketChannel的接收缓冲区;
  • Work线程负责生成相应事件,触发事件向上执行,调度到ChannelPipeline中;
  • Word线程调度Handler链的对应方法;
  • 业务方法放在线程池中并发执行(ExecutionHandler维护),work线程返回;

Out:

  • Netty将写操作封装成写事件,触发事件向下传播;
  • 业务线程将编码后的消息Push到发送队列中,然后返回;
  • Netty的work线程从队列中取出消息,调用SocketChannel的write方法写入通道。

分析:

    Outbound操作由业务线程执行,通常业务会使用线程池并行处理业务消息,这就意味着在某一个时刻会有多个业务线程同时操作ChannelHandler,我们需要对ChannelHandler进行并发保护,通常需要加锁。如果同步块的范围不当,可能会导致严重的性能瓶颈,这对开发者的技能要求非常高,降低了开发效率;

    Outbound操作过程中,例如消息编码异常,会产生Exception,它会被转换成Inbound的Exception并通知到ChannelPipeline,这就意味着业务线程发起了Inbound操作!它打破了Inbound操作由I/O线程操作的模型,如果开发者按照Inbound操作只会由一个I/O线程执行的约束进行设计,则会发生线程并发访问安全问题。由于该场景只在特定异常时发生,因此错误非常隐蔽!一旦在生产环境中发生此类线程并发问题,定位难度和成本都非常大。

 

4.x 线程模型

In and Out:

  • I/O线程NioEventLoop从SocketChannel中读取数据报,将ByteBuf投递到ChannelPipeline,触发ChannelRead事件;
  • I/O线程NioEventLoop调用ChannelHandler链,直到将消息投递到业务线程,然后I/O线程返回,继续后续的读写操作;
  • 业务线程调用ChannelHandlerContext.write(Object msg)方法进行消息发送;
  • 如果是由业务线程发起的写操作,ChannelHandlerInvoker将发送消息封装成Task,放入到I/O线程NioEventLoop的任务队列中,由NioEventLoop在循环中统一调度和执行。放入任务队列之后,业务线程返回;
  • I/O线程NioEventLoop调用ChannelHandler链,进行消息发送,处理Outbound事件,直到将消息放入发送队列,然后唤醒Selector,进而执行写操作。

分析:

    Netty 4采用了串行化设计理念,从消息的读取、编码以及后续Handler的执行,始终都由I/O线程NioEventLoop负责,这就意外着整个流程不会进行线程上下文的切换。

    每当有一个新的客户端接入,则从NioEventLoop线程组中顺序获取一个可用的NioEventLoop,当到达数组上限之后,重新返回到0,通过这种方式,可以基本保证各个NioEventLoop的负载均衡。一个客户端连接只注册到一个NioEventLoop上,这样就避免了多个I/O线程去并发操作它。

(1)EventLoopGroup继承自EventExecutorGroup,而EventExecutorGroup可以将它看成是一个线程池,而EventLoopGroup只不过是扩展了了线程池的功能,加入了一些事件的处理。例如channel的注册等。

(2)EventLoop继承自EventExecutor,而一个EventExecutor可以将其看成是一个线程池中的执行线程,而EventLoop扩展了EventExecutor的主循环,一般情况下线程池中的线程要做的就是不断的从任务队列里面取Task,然后执行他们,而EventLoop中加入了select以及IO的处理过程。

(3)每一个channel都注册到了其中一个EventLoop的selector上面,在这个channel上面产生的所有IO事件的处理都将会是在这个EventLoop中进行处理。

转载于:https://my.oschina.net/marvelcode/blog/1421867

你可能感兴趣的文章
Packet for query is too large (12238 > 1024). You can change this value
查看>>
加密类型以及相关算法
查看>>
生产者和消费者问题,但还是对其中的notify()方法不明白
查看>>
c++ 11 新特性
查看>>
管理控制文件
查看>>
Jersey 2.x 运行项目
查看>>
通过help()自学Python
查看>>
Rocketmq
查看>>
《中国智慧》
查看>>
springmvc经典教程(5)
查看>>
java实现手机短信验证全过程
查看>>
Oracle RAC Study之--Oracle 10g RAC 故障之--CRS启动失败
查看>>
(转) Linux下生成动态链接库是否必须使用 -fPIC 的问题
查看>>
程序员的一生,目标、基础、技巧、理念、孕期、要求
查看>>
linux mail用法
查看>>
Java 并发:第六部分 - 原子变量
查看>>
关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]...
查看>>
大型网站技术架构剖析
查看>>
linux六周第一次课(3月12日)笔记
查看>>
cisco LAN Base 、IP Base 、IP Server 区别
查看>>