Netty的線程模式

來源:互聯網
上載者:User

原文連結 http://netty.io/wiki/thread-model.html

To put simply, for a channel: Regardless of its transport and type, its all upstream (i.e. inbound) events must be fired from the thread that performs I/O for the channel (i.e. I/O thread). All downstream (i.e. outbound) events can be triggered from any thread including the I/O thread and non-I/O threads. However, any upstream events triggered as a side effect of the downstream event must be fired from the I/O thread. (e.g. IfChannel.close() triggers channelDisconnected, channelUnbound, and channelClosed, they must be fired by the I/O thread. 對於Channel的簡單介紹: 無論哪種傳輸類型,所有的上行事件必須由I/O線程產生。 所有的下行訊息可以在I/O線程中產生也可以在非I/O線程中產生。任何由下行事件觸發的上行事件都必須在I/O線程中產生。例如由Channel.close()所觸發的channelDisconnected,channelUnbound 和 channelClosed都是在I/O線程中產生的。

Current problems (UGLY - causes a race condition in an upstream handler, BAD - does not cause a race condition but violates the expected thread model): UGLY: The upstream events triggered as a side effect of a downstream event is triggered by the caller thread, UGLY: The local transport always uses a caller thread to trigger an event.

BAD: channelOpen is triggered by the thread that called ChannelFactory.newChannel(), which is not an I/O thread. It's kind of bad but otherwise its not possible to limit the concurrent active channels by closing the channel here. If we would do this in the IO-Thread it would not be that efficient.

BAD: Client-side channels are run by two I/O threads. One that makes a connection attempts and the other that does actual I/O.

現在的問題有兩2方面,UGLY-在上行的handler中產生競爭條件,BAD- 不會產生競爭條件,但是違反了預期的執行緒模式 UGLY:調用線程產生了一個下行事件觸發的上行事件。 UGLY: 本地傳輸層總是使用調用線程觸發事件 BAD:channelOpen 由調用ChannelFactory.newChannel()的線程觸發,而不是由I/O線程觸發。這種方式不好,但我們不能通過關閉Channel來限制當前並發的Channel。如果我們要在I/O線程中做這件事效率不會很高。 BAD: 用戶端的channel運行在兩個線程中。一個處理串連,另一個用來處理實際的I/O操作。

Action items: Merge client-side boss, server-side boss, and NioWorker into a universal I/O thread that can perform all I/O operations. By doing this: We solve the client-side channel problem because the thread which attempted a connection attempt can continue to perform reads and writes. We solve the problem where Netty creates as many threads as the number of open server ports. We can share a pool of NioWorkers more easily and will potentially have more flexibility in channel-worker mapping. We also need to investigate if we can make an abstract I/O thread class so that all transports (socket, datagram, SCTP, ..) can extend it. We currently have too much duplication between socket, datagram, and SCTP. If the caller thread is not the I/O thread, Netty triggers an upstream event later in the I/O thread. Along with this change, allow a user to trigger one's own upstream event later in the I/O thread by adding the sendUpstreamLater() method to ChannelPipeline and ChannelHandlerContext. However, we cannot use sendUpstreamLater() only if the current thread is not the I/O thread because OMATPE or MATPE will interfere with it, so we will have to let user decide. (i.e. to call sendUpstream() or sendUpstreamLater()) ChannelFactory.newChannel() must not trigger an event immediately. newChannel() must wait until the I/O thread notifies the channel has been registered to the I/O thread, before returning the new channel to the caller.
Rewrite the local transport. 解決方案 將用戶端的boss, 伺服器端的boss和woker合并到一個通用的I/O線程中來執行所有I/O操作。要解決用戶端的問題可以在嘗試串連的線程中繼續處理讀寫操作;我們解決了Netty要建立和伺服器已開啟連接埠數目相同的線程的問題;我們可以採用一個NioWorkers池來供多個channel-worker共同使用;我還需要研究採用一個抽象的I/O線程來供所有傳輸方式擴充。目前我們在socket,datagram, sctp之間有很多重複的東西。 如果調用線程不是I/O線程,Netty將會在I/O線程中觸發上行訊息。這種方式允許使用者在ChannelPipeline 和 ChannelHandlerContext中添加sendUpstreamLater()方法到I/O線程中來觸發上行訊息。但是我們不能在非I/O線程中使用sendUpstreamLater(),因為OMATPE 或 MATPE會干擾它(這一句沒搞懂什麼意思),所以必須讓使用者自己決定。(調用sendUpstream() 或 sendUpstreamLater()) ChannelFactory.newChannel()並不會立即觸發一個事件,而是要等待I/O線程通知channel已經註冊到I/O線程了,在新channel返回給調用者之前。 重新本地傳輸。

Questions: Can we make all these changes in v3 and keep things still backward-compatible? Wouldn't it be easier to get this done in v4? Fully asynchronous user application which does all I/O in an handler making heavy use of ChannelFuture shouldn't be affected by the current flawed thread model, which means a user can some how work around this issue, so it might be better move on to v4 instead of making the same changes on two branches. 問題: 對V3版本做的改動能否保持向後相容。能否很容易的遷移到V4版本了。在I/O handler中使用大量ChannelFuture的非同步程式不應受到當前不合理執行緒模式的影響,意味著使用者如何解決這個問題,因此我們應該快速的遷移到V4版本。

Answers: I think if its to much work to "backport" it to v3 we should just move ahead and "ignore" it for v3. Maybe we can find some "easier" workaround for v3 which would at least help us to get rid of the Channel.close() race, as this is the one that will most likely hit our users. (normanmaurer) 答案: 反向移植的V3版本要花很多工作,那麼我們應該遷移到最新版本上。也許我們會發現我們的項目採用V3版本可以讓我們很容易的避免Channel.close()的競爭。

本文還有很多地方不理解,如果您有好的翻譯歡迎補充。




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.