攜手共進——《NettyINACTION》中文版《Netty實戰》答疑解惑

千萬別惹貓發表於2017-06-07

引子

所謂一千個人的眼中,就會有一千個哈姆雷特,每位讀者對於一本書中的意境的理解都是不一樣的,當然這也包括技術類書籍。可是對於技術書籍來說,最重要的就是準確性,這種準確性是要求100%的,不能說“千人千面”。作為書籍的作者和譯者,自然在表達的時候可能有所紕漏,不能做到面面俱到,所以也就有了這篇小文,用來收集以及解答譯者收到的讀者的一些反饋和疑問,希望能夠幫助到大家。

共進

  • 書中說的每一個Channel都具有唯一的id是什麼意思呢,如果返回相同的hashCode就會報錯?

解惑:書中對於這一塊兒的描述其實不是特別的詳細,只是給出了結論,但是並沒有給出為何。首先id的意思是identity,即唯一標識,類似於我們的身份證。那麼為何Channel的唯一標識必須是唯一的呢?這是因為一個網路連線(這裡不指面向連線、或者無連線的協議)總是由一個(SourceIP,SourcePORT,TargetIP,targetPORT )唯一確定的,這個四元組是不會重複的吧,這裡排除(IP和埠)複用的情況。所以這就是為何設計成每個Channel的id都是唯一確定的。具體的可以檢視io.netty.channel.AbstractChannel#compareTo的程式碼。那麼有什麼時候報錯呢,如上面的程式碼,即呼叫compareTo的時候。一個很常見的場景便是通過呼叫ChannelGroupadd(Channel)方法,將一個Channel新增到ChannelGroup時,其中ChannelGroup的內部使用了由ConcurrentHasmMap實現的ConcurrentHashSet,說到這裡,讀者應該明白了吧,因為後面的邏輯,compareTo的呼叫已經是HashMap的邏輯了。

  • 書中說的當一個Channel被標記為@Shareable的時候才可以被同時新增到多個ChannelPipeline中,否則的話就會報錯,這是為何呢?

解惑:書中並沒有提到原始碼層面是如何實現的,實際上,在 Netty 目前基於 EventLoop 的執行緒模型中,Netty 是要求使用者的ChannelHandler的實現必須要是執行緒安全的。這樣,其便可以在不同的ChannelChannelPipeline中安全的共享。所以,設計上為了避免非執行緒安全的ChannelHandler被錯誤地共享,所以 Netty 要求你標註一個ChannelHandler@Shareable來指示它的執行緒安全性。在內部,每一個ChannelHandler都有一個isAdded欄位,這個欄位在ChannelPipelineadd/set*(ChannelHandler)被呼叫的時候將會讀取。原始碼見:io.netty.channel.ChannelHandlerAdapter#addedio.netty.channel.DefaultChannelPipeline#checkMultiplicity

如果大家還有什麼不明白,可以在下面留言、


相關文章