Netty是一個高性能、異步事件驅動的NIO框架,它提供了對TCP、UDP和文件傳輸的支持,做爲一個異步NIO框架,Netty的全部IO操做都是異步非阻塞的,經過Future-Listener機制,用戶能夠方便的主動獲取或者經過通知機制得到IO操做結果。數組
做爲當前最流行的NIO框架,Netty在互聯網領域、大數據分佈式計算領域、遊戲行業、通訊行業等得到了普遍的應用,一些業界著名的開源組件也基於Netty的NIO框架構建。性能優化
Netty架構分析網絡
Netty 採用了比較典型的三層網絡架構進行設計,邏輯架構圖以下所示:多線程
第一層:Reactor 通訊調度層,它由一系列輔助類完成,包括 Reactor 線程 NioEventLoop 以及其父類、NioSocketChannel/NioServerSocketChannel 以及其父類、ByteBuffer 以及由其衍生出來的各類 Buffer、Unsafe 以及其衍生出的各類內部類等。該層的主要職責就是監聽網絡的讀寫和鏈接操做,負責將網絡層的數據讀取到內存緩衝區中,而後觸發各類網絡事件,例如鏈接建立、鏈接激活、讀事件、寫事件等等,將這些事件觸發到 PipeLine 中,由 PipeLine 充當的職責鏈來進行後續的處理。架構
第二層:職責鏈 PipeLine,它負責事件在職責鏈中的有序傳播,同時負責動態的編排職責鏈,職責鏈能夠選擇監聽和處理本身關心的事件,它能夠攔截處理和向後/向前傳播事件,不一樣的應用的 Handler 節點的功能也不一樣,一般狀況下,每每會開發編解碼 Hanlder 用於消息的編解碼,它能夠將外部的協議消息轉換成內部的 POJO 對象,這樣上層業務側只須要關心處理業務邏輯便可,不須要感知底層的協議差別和線程模型差別,實現了架構層面的分層隔離。併發
第三層:業務邏輯處理層,能夠分爲兩類:框架
1.純粹的業務邏輯處理,例如訂單處理。異步
2.應用層協議管理,例如HTTP協議、FTP協議等。分佈式
接下來,我從影響通訊性能的三個方面(I/O模型、線程調度模型、序列化方式)來談談Netty的架構。高併發
這裏推薦一下個人Java架構學習羣:479499375 ,羣裏有(Java高架構、分佈式架構、高可擴展、高性能、高併發、性能優化、Spring boot、Redis、ActiveMQ、等學習資源)進羣免費送給每一位Java小夥伴,無論你是轉行,仍是工做中想提高本身能力均可以!
IO模型
Netty的I/O模型基於非阻塞I/O實現,底層依賴的是JDK NIO框架的Selector。
Selector提供選擇已經就緒的任務的能力。簡單來說,Selector會不斷地輪詢註冊在其上的Channel,若是某個Channel上面有新的TCP鏈接接入、讀和寫事件,這個Channel就處於就緒狀態,會被Selector輪詢出來,而後經過SelectionKey能夠獲取就緒Channel的集合,進行後續的I/O操做。
線程調度模型
經常使用的Reactor線程模型有三種,分別以下:
1.Reactor單線程模型:Reactor單線程模型,指的是全部的I/O操做都在同一個NIO線程上面完成。對於一些小容量應用場景,可使用單線程模型。
2.Reactor多線程模型:Rector多線程模型與單線程模型最大的區別就是有一組NIO線程處理I/O操做。主要用於高併發、大業務量場景。
3.主從Reactor多線程模型:主從Reactor線程模型的特色是服務端用於接收客戶端鏈接的再也不是個1個單獨的NIO線程,而是一個獨立的NIO線程池。利用主從NIO線程模型,能夠解決1個服務端監聽線程沒法有效處理全部客戶端鏈接的性能不足問題。
序列化方式
影響序列化性能的關鍵因素總結以下:
1.序列化後的碼流大小(網絡帶寬佔用)
2.序列化&反序列化的性能(CPU資源佔用)
3.併發調用的性能表現:穩定性、線性增加、偶現的時延毛刺等
這裏推薦一下個人Java架構學習羣:479499375 ,羣裏有(Java高架構、分佈式架構、高可擴展、高性能、高併發、性能優化、Spring boot、Redis、ActiveMQ、等學習資源)進羣免費送給每一位Java小夥伴,無論你是轉行,仍是工做中想提高本身能力均可以!
鏈路有效性檢測
心跳檢測機制分爲三個層面:
1.TCP層面的心跳檢測,即TCP的Keep-Alive機制,它的做用域是整個TCP協議棧;
2.協議層的心跳檢測,主要存在於長鏈接協議中。例如SMPP協議;
3.應用層的心跳檢測,它主要由各業務產品經過約定方式定時給對方發送心跳消息實現。
心跳檢測的目的就是確認當前鏈路可用,對方活着而且可以正常接收和發送消息。做爲高可靠的NIO框架,Netty也提供了基於鏈路空閒的心跳檢測機制:
1.讀空閒,鏈路持續時間t沒有讀取到任何消息;
2.寫空閒,鏈路持續時間t沒有發送任何消息;
3.讀寫空閒,鏈路持續時間t沒有接收或者發送任何消息。
零拷貝
· 使用getByte(int index)方法來實現隨機訪問
· 使用雙指針的方式實現順序訪問
· Netty主要實現了HeapChannelBuffer,ByteBufferBackedChannelBuffer,與Zero Copy直接相關的CompositeChannelBuffer類
Netty 的 Zero-copy 體如今以下幾個個方面:
l Netty 提供了 CompositeByteBuf 類, 它能夠將多個 ByteBuf 合併爲一個邏輯上的 ByteBuf, 避免了各個 ByteBuf 之間的拷貝。
l 經過 wrap 操做, 咱們能夠將byte[] 數組、ByteBuf、ByteBuffer等包裝成一個 Netty ByteBuf 對象, 進而避免了拷貝操做。
l ByteBuf 支持 slice 操做,所以能夠將 ByteBuf 分解爲多個共享同一個存儲區域的ByteBuf, 避免了內存的拷貝。
l 經過 FileRegion 包裝的FileChannel.tranferTo 實現文件傳輸, 能夠直接將文件緩衝區的數據發送到目標 Channel, 避免了傳統經過循環 write 方式致使的內存拷貝問題。