《Netty官方指南》线程模型

原文链接 译者:Johnson

你知道本页的内容是自动生成自Github 维基页面吗?你可以点击这里改进它.


对应一个channel而言:

  1. 无论其transport和类型,它的所有upstream(例如inbound)事件都必须由负责该channel I/ O的线程触发(也就是I/O线程)。
  2. 所有downstream(例如 outbound)事件能够被包括I/O线程或非I/O线程的任一线程触发。
    然而,任何作为downstream事件附带所触发的upstream事件都必须由I/O线程触发(例如 如果 Channel.close()触发channelDisconnected,channelUnbound,和channelClosed事件,他们必须由 I/O线程触发)。

当前的问题

(UGLY-在upstream handler中引起竞态条件,BAD-不会引起竞态条件但是会违反所期待的线程模型):

  • UGLY:由downstream事件副作用所触发的upstream事件被调用线程所触发,UGLY:本地transport
    总是通 过线程 直接触发事件。
  • UGLY:本地transport总是通过线程直接触发事件。
  • BAD:channelOpen 被非I/O线程调用ChannelFactory.newChannel()而触发.这有点糟糕,但是如果不这么做的话,我们不能通过关闭channel来实现对并发活跃channel的限制.如果我们在IO 线程中这样做,将会比较低效。
  • BAD:客户端的channel由两个线程负责,一个负责创建链接,另一个负责实际的I/O。

生效列表:

  • 通过将客户端boss,服务器端boss与NioWorker合并到统一的I/O线程中:
    • 我们解决了用户的channel的问题,处理链接的线程能够继续读和写。
    • 我们解决了netty会因为开放连接过多而导致的线程创建过多的问题。
    • 我们可以更加容易地通过NioWorker池共享NioWorker从而使得channel- worker的映射更加灵活。
    • 我们也应当研究是否能够创建一个抽象的I/O线程类以便所有的 transport(socket,datagram,SCTP...)都可以从它扩展,当前在socket,datagram 和 SCTP间有太多冗余。
  • 如果调用线程不是I/O线程,Netty会触发I/O线程的upstream事件,通过这种改变,使得用户可以通过添加到ChannelPipeline 和 ChannelHandlerContext上的sendUpStreamLater()方法来手动 触发upstream事件。
    • 然而,只有当当前的线程不是I/O线程的时候我们才能使用sendUpstreamLater()方法,因为OMATPE或 MATPE会与它冲突,所以我们留个用户自己决定(也就是调用sendUpstream()或 sendUpstreamLater())。
  • ChannelFactory.newChannel()不能立即触发任何事件,newChannel()必须等到I/O线程通知 channel已经被注册到I/O线程后才能返回新的channel对象给调用者。
  • 重写本地transport。

问题:

在V4版本中实现这些不是更容易吗?通过在handler中使用ChannelFuture实现所有I/O的完全异步的用户程序应该不会受到现有不完善线程模型的影响,也就是说用户可以忽略这个问题,所以最好是在V4 中实现这些变更而不是在V3和V4两个分支中实现。

答案:

我在想着是否这对v3版本来说有点多了,我们应该向前推进而暂时忽略这些问题,或许我们可以有更加变通的办法使得v3能够至少帮助我们解决当前最困扰用户的Channel.close()问题。

Last retrieved on 10-Mar-2017

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 《Netty官方指南》线程模型

  • Trackback 关闭
  • 评论 (0)
  1. 暂无评论

return top