大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java高階必備之Netty基礎原理

Java高階必備之Netty基礎原理

更新時間:2019-08-04 09:00:00 來源:動力節(jié)點 瀏覽2503次

   


  Netty是Java程序員通向高階之路必須要過的門檻之一。干了幾年的Java程序員發(fā)現(xiàn)業(yè)務開發(fā)似乎就是在SSH的世界里摸滾打爬的時候,會開始感到迷茫,難道程序員的日子就是如此枯燥么?深入使用一下Netty,另一個世界的大門就會開始打開??菰锏木幋a會漸漸變得有趣,自主思考的能力也會開始加強。


  Netty是建立在Java NIO基礎之上最廣泛使用的高性能網(wǎng)絡框架。了解Netty之前,必須對NIO的概念有所了解。


  NIO的意思是非阻塞IO,也就是說單個線程可以同時進行多個IO操作,而不會被任何IO操作阻塞住。同一個線程即能同時Accept網(wǎng)絡套件字,又可以同時對套件字進行讀寫操作,然后還可以同時處理消息。

  NIO基于事件機制,所有的IO操作都能抽象成一個事件。當新連接到來時,可以從內核中拿到ServerSocket的可讀事件。當連接上的消息到來時,可以從內核中拿到Socket的讀事件。當Socket中的緩沖區(qū)未滿的時候,可以從內核中拿到Socket的可寫事件。


  當NIO線程從內核中拿到一個事件Event,就會開始使用相應的事件處理器EventHandler對這個事件進行處理。如果拿到ServerSocket可讀事件,就會調用ServerSocket.accept獲取一個新的Socket連接,然后將這個Socket連接加入到感興趣的描述符列表中,如果拿到Socket可讀事件就會開始調用Socket.read讀取套件字的消息進行處理,處理完畢將返回結果序列化成一個字節(jié)數(shù)組,當Socket可以拿到可寫事件時,說明套件字緩沖區(qū)未滿,就拼命的將字節(jié)數(shù)組往Socket里灌,也就是調用Socket.write進行IO的寫操作。



  1.png

 

  NIO從內核中拿事件的操作使用的是Selector.select函數(shù)調用,它對應操作系統(tǒng)界面的IO多路復用API。在現(xiàn)代操作系統(tǒng)里mac平臺上對應的是kqueue模型,linux平臺對應的是epoll模型,windows平臺對應的是iocp模型。Java是一個跨平臺的語言,JVM底層對操作系統(tǒng)的具體實現(xiàn)進行了抽象,統(tǒng)一向上層提供的是Selector系列API。用戶只需要使用Selector提供的通用API來處理NIO相關功能即可,而無需關系底層具的操作系統(tǒng)API的差別了。


  Selector可以理解為一個描述符對象[SocketChannel]列表,Selector通過調用操作系統(tǒng)API,傳遞一個描述符列表參數(shù),然后就可以拿到內核提供的與所有的描述符相關的事件[Key]列表。

 

2.png 


  上面提到的NIO線程是一個單線程,但是實際上它可以是一個線程池,線程池中的每個線程負責一部分描述符的讀寫操作。它也可以是兩個線程池,一個線程池只用來處理ServerSocket描述符建立新連接,另一個線程池專門干Socket讀寫的事。


 3.png 


  Netty提供了良好的封裝,可以讓我們很方便的配置線程池的功用。代碼中的NioEventLoopGroup代表的就是一個線程池,池中每個線程都是一個獨立的NioEventLoop,即Nio事件循環(huán)。當acceptor線程池接收到一個新連接后會將這個連接通過隊列發(fā)送到讀寫線程池繼續(xù)進行處理。線程池分開的好處是當讀寫線程池繁忙的時候不影響acceptor接收新連接。


  NIO的讀寫操作也是一系列復雜的過程。當NIO讀事件發(fā)生時,線程使用read操作讀取到的消息可能是不完整的,剩下的部分可能還要在接下來多次讀事件發(fā)生后才能讀到完整的一個消息對象字節(jié)數(shù)組。也可能read操作讀取到的消息包含多個消息對象,最后剩下的部分又是一個不完整的消息,這就需要在每個描述符關聯(lián)對象中保存中間半包的狀態(tài)。消息和消息之間又有組合關系,比如HTTP POST消息包含HTTP Header和HTTP Body兩個部分,而HTTP Body又可能因為太大而分解為多個HTTP Chunks進行傳輸,這就要求NIO的讀寫消息的設計包含結構層級。寫操作也不是一個簡單的write操作就了事了,寫操作要考慮到內核為每個套件字分配的buffer大小,如果buffer不夠了,write寫進去的數(shù)組是不能完全寫進去的,寫不進去的字節(jié)數(shù)據(jù)必須保留起來,等待下次寫事件發(fā)生時,也就是內核緩沖有空閑空間了,才可以將剩下的數(shù)據(jù)發(fā)送過去。

 

4.png 


  Netty將消息的讀寫抽象為pipeline消息管道,結構上有點類似于計算機網(wǎng)絡分層結構。pipeline的每一層會對應一個Handler,以上一層輸出的消息結構作為輸入,輸出新的消息結構作為下一層的輸入。pipeline對象掛接在每一個Socket鏈路上。

  

5.png 


  代碼中我們在pipeline里定義了四層Handler,第一個是處理ReadTimeout,當一個連接長達60s沒有任何消息的情況下會向下一層輸出一個讀超時消息。第二層是一個Redis消息解碼器,將Socket中的字節(jié)流轉換成Redis命令對象,第三層是一個Redis消息編碼器,將Redis輸出對象轉稱字節(jié)流,第四層是消息處理器,用來逐個處理Redis命令邏輯,這里一般就是我們復雜的業(yè)務邏輯所在地,我們會在業(yè)務邏輯里最終給Socket回饋消息輸出,這個消息輸出又會走一遍pipeline的每一層,直到轉換成字節(jié)流寫到內核socket緩沖區(qū)中才算完事。


  然后我們設置一些套件字的特殊屬性,比如監(jiān)聽隊列大小、讀寫緩沖警戒水位大小、是否延遲發(fā)送等,然后綁定監(jiān)聽指定端口,服務器就可以開始永無止盡地工作了。



提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 国产亚洲一欧美一区二区三区 | 亚洲综合激情九月婷婷 | 欧美日韩北条麻妃一区二区 | 国产区一区二区三区 | 国产四虎精品 | 麻豆国产精品免费视频 | 亚洲一区二区三区高清不卡 | 色鬼综合 | 奇米777影视成人四色 | 奇米影视在线播放 | 成人精品一区二区不卡视频 | 欧美亚洲精品小说一区二三区 | 蜜桃破解版免费看nba | 亚洲欧美一区二区三区在线播放 | 日韩视频区 | 伊人一区二区三区 | 亚洲图片国产日韩欧美 | vr欧美乱强伦xxxxx | 综合免费一区二区三区 | 欧美成人免费 | 日本乱中文字幕系列在线观看 | 国产一区二区三区不卡在线观看 | 日本人一级毛片免费视频 | 97久久精品人人做人人爽 | 五月婷婷久久综合 | 香蕉视频伊人 | 日韩免费在线观看 | 国产51自产区 | 天天爽夜夜爽人人爽 | 国产成人a v在线影院 | 久热亚洲 | 亚洲 欧美 国产另类首页 | 欧洲毛片真人 | 国产精品青草久久 | 亚洲综合欧美日韩 | 成人精品福利 | 99毛片| 久热在线视频精品网站 | 久久精品女人毛片国产 | 二性视频 | 久久免费国产精品一区二区 |