從tcp到netty(二)


 

 

(二)

Netty源碼分析

做一套rpc長連接框架,架構上其實沒有多么難,只要具體里面的步驟包括即可:

一、全雙工的socket連接;

二、心跳檢測

三、超時重連、重傳

四、白名單

五、編解碼

 

  這里還有相當多的技術規范與技術點,比如tcp消息封裝定義消息頭、消息體;定義反射類與方法用於遠程方法執行;主從線程與線程池的設定;編解碼序列的定義;粘包、拆

包,涉及到tcp報文包的分片;網絡的流量、擁塞控制;編解碼中的大小端;buffer數據解析等。

  其實,我不得不吐槽一下,netty源碼分析那本書有些地方並不好,有些地方沒有按照思維邏輯去講解,而是按照執行順序,這樣其實並不符合這么一個項目的構建過程!

  還有一點,講太細致,太深入,如果要全部分析完成,恐怕會非常耗時,其實很多只需要整體把握,如果有時間再慢慢消化!

全雙工連接

  對於java來說,原生的java nio,其存在固有的復雜性與bug,難以令人滿意!而netty則將用戶邊界做了封裝,降低用戶的開發難度,實際上我對於netty這本書的講解流程並不滿

意,因為它是按照代碼的執行順序講解的,實際上並不符合人的思維邏輯;接下來我將會先從書中將的內容順序梳理,然后再通過思維流程進行梳理一遍。

  首先要通過epoll理解buffer與channal!這兩者是不同的,channal從物理上將是位於機器的內核空間,處於一個接收網絡數據、本地文件數據等一系列前置底層的數據操作!

buffer則不然,對於java來說,就是為了將這些數據進行結構化,同時在物理上講這是一種位於用戶空間,也就是java進程中為了與對應java基本數據類型等的映射!

 

Server端:

一、根據netty權威指南,ServerBootstrapsocket服務端的啟動輔助類,用途是封裝啟動參數

二、使用綁定Reactor線程池,處理多路復用的管道channal (netty書上說使用EventLoopGroup,但是我沒有找到對應類的源碼,可能讀的不夠深吧),也就是連接;

三、使用ServerSocketChannel嫁接數據 =》處理活躍連接的管道上,處理活躍連接;

四、ChannalPipeline這一步應該並不歸於建立連接!用於處理請求數據的,比如驗證信息、編碼解碼、心跳檢測、流量控制等;

五、綁定監聽端口,ServerSocketChannal注冊到Selector(多路復用器,也就是為了處理epoll中的epoll_wait活躍事件)

六、輪詢Selector,找出對應的Channal;

 

最終建立連接會有一個listen方法傳入文件描述符、backlog,具體的實現類方法可以看

 

這個類,會發現一個這樣的方法

 

  最終調用native的c函數獲取操作系統的描述符,建立連接。關於backlog這個參數

是內核為此套接字排隊的最大連接的個數。

  然后關於建立連接使用的兩個隊列:未連接隊列、已連接隊列,就是涉及到tcp的相關知識了!如果是建立連接的時候客戶端發送syn報文段,此時未連接隊列創建一個節點,當

server端發送syn與ack報文段之后一直到server端收到client端的ack報文段之前一直處於未連接隊列;如果server端收到client的第三次握手ack,則將未連接隊列的此節點移動到已完

成連接隊列的隊尾。系統默認為5,一般都會進行設置用以支持高並發!

 

  正是因為不同的操作方式,所以有了不同的操作位!SelectionKey,中有四個常量分別為OP_READ、OP_WRITE、OP_ACCEPT、OP_CONNECT,用於表示不同的事件。這

樣切合了事件機制。這四種常量分別為針對1的位操作,分別為1、4、8、16,對應二進制位為0001、0100、1000、10000;書上指定是說錯了的!使用位操作的優勢,說是方便網

絡操作位狀態的判斷與修改,這我可以理解,因為如果都轉成二進制的話,在數據結構上更方便轉換,但是我不理解的是為什么不適用0001、0010、0100、1000呢?后續再考量這

到底是怎么回事!

 

  基本上整體思路就是這樣,具體到內部還有很多相關於java的內容,比如為什么ChannalHanlder使用volatile?Volatile只保證了可見性,沒有保證原子性,我也沒有找到它需要

保證原子性的操作,那么是它不需要保證原子性還是再更深處的地方做了處理?

 

Client端:

終於到了client端了!關於這塊暫時不具體考慮netty的實現,而且不再按照書上說的代碼執行順序講,具體的后續補發!

一、建立雙工連接,可以使用NioSocketChannal、SocketChannal;

二、根據tcp的三次握手報文段,確認SelectionKey的枚舉類型;

三、如果進入ChannalActive階段,也就是epoll中epoll_waite活躍的連接,則設置網絡操作位為SelectionKey.OP_READ階段,否則連接到selector(多路復用器)階段;

 

 ==========================================================================================================================

 

 

                      篇章二 - 定義request、response

                      篇章三 - 超時重傳、心跳檢測

                      篇章四 - 負載均衡

                      篇章五 - 服務平台管理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM