《Netty官方指南》執行緒模型
阿新 • • 發佈:2018-12-23
原文連結 譯者:Johnson
對應一個channel而言:
- 無論其transport和型別,它的所有upstream(例如inbound)事件都必須由負責該channel I/ O的執行緒觸發(也就是I/O執行緒)。
- 所有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