netty實戰之一 認識netty
一.netty是啥?
百度百科簡介:
Netty是由JBOSS提供的一個java開源框架。Netty提供非同步的、事件驅動的網路應用程式框架和工具,用以快速開發高效能、高可靠性的網路伺服器和客戶端程式。
也就是說,Netty 是一個基於NIO的客戶、伺服器端程式設計框架,使用Netty 可以確保你快速和簡單的開發出一個網路應用,例如實現了某種協議的客戶、服務端應用。Netty相當於簡化和流線化了網路應用的程式設計開發過程,例如:基於TCP和UDP的socket服務開發。
“快速”和“簡單”並不用產生維護性或效能上的問題。Netty 是一個吸收了多種協議(包括FTP、SMTP、HTTP等各種二進位制文字協議)的實現經驗,並經過相當精心設計的專案。最終,Netty 成功的找到了一種方式,在保證易於開發的同時還保證了其應用的效能,穩定性和伸縮性。
簡單來說就是netty是JBoss做的一個Jar包,為了快速開發高效能、高可靠性的網路伺服器和客戶端程式,可以提供非同步的、事件驅動的網路應用程式框架和工具
netty組成(後續文章會詳細介紹)
我們可以先從總體上認識一下Netty用到的元件及它們在整個Netty架構中是怎麼協調工作的。Netty應用中必不可少的元件:
- Bootstrap or ServerBootstrap
- EventLoop
- EventLoopGroup
- ChannelPipeline
- Channel
- Future or ChannelFuture
- ChannelInitializer
- ChannelHandler
Bootstrap,一個Netty應用通常由一個Bootstrap開始,它主要作用是配置整個Netty程式,串聯起各個元件。
Handler,為了支援各種協議和處理資料的方式,便誕生了Handler元件。Handler主要用來處理各種事件,這裡的事件很廣泛,比如可以是連線、資料接收、異常、資料轉換等。
ChannelInboundHandler,一個最常用的Handler。這個Handler的作用就是處理接收到資料時的事件,也就是說,我們的業務邏輯一般就是寫在這個Handler裡面的,ChannelInboundHandler就是用來處理我們的核心業務邏輯。
ChannelInitializer,當一個連結建立時,我們需要知道怎麼來接收或者傳送資料,當然,我們有各種各樣的Handler實現來處理它,那麼ChannelInitializer便是用來配置這些Handler,它會提供一個ChannelPipeline,並把Handler加入到ChannelPipeline。
ChannelPipeline,一個Netty應用基於ChannelPipeline機制,這種機制需要依賴於EventLoop和EventLoopGroup,因為它們三個都和事件或者事件處理相關。
EventLoops的目的是為Channel處理IO操作,一個EventLoop可以為多個Channel服務。
EventLoopGroup會包含多個EventLoop。
Channel代表了一個Socket連結,或者其它和IO操作相關的元件,它和EventLoop一起用來參與IO處理。
Future,在Netty中所有的IO操作都是非同步的,因此,你不能立刻得知訊息是否被正確處理,但是我們可以過一會等它執行完成或者直接註冊一個監聽,具體的實現就是通過Future和ChannelFutures,他們可以註冊一個監聽,當操作執行成功或失敗時監聽會自動觸發。總之,所有的操作都會返回一個ChannelFuture。
2.1netty重要元件的關係圖解
- 2.1.1.ServerBootstrap及Bootstrap的類繼承結構圖
- 2.1.2.下圖是Channel、EventLoop、Thread、EventLoopGroup之間的關係(摘自《Netty In Action》):
- 2.1.2 下圖顯示了ServerBootstrap的兩個EventLoopGroup
二.netty能幹嘛?
Netty 在哪些行業得到了應用?網際網路行業:隨著網站規模的不斷擴大,系統併發訪問量也越來越高,傳統基於 Tomcat 等 Web 容器的垂直架構已經無法滿足需求,需要拆分應用進行服務化,以提高開發和維護效率。從組網情況看,垂直的架構拆分之後,系統採用分散式部署,各個節點之間需要遠端服務呼叫,高效能的 RPC 框架必不可少,Netty 作為非同步高效能的通訊框架,往往作為基礎通訊元件被這些 RPC 框架使用。典型的應用有:阿里分散式服務框架 Dubbo 的 RPC 框架使用 Dubbo 協議進行節點間通訊,Dubbo 協議預設使用 Netty 作為基礎通訊元件,用於實現各程式節點之間的內部通訊。
其中,服務提供者和服務消費者之間,服務提供者、服務消費者和效能統計節點之間使用 Netty 進行非同步/同步通訊。除了 Dubbo 之外,淘寶的訊息中介軟體 RocketMQ 的訊息生產者和訊息消費者之間,也採用 Netty 進行高效能、非同步通訊。除了阿里系和淘寶系之外,很多其它的大型網際網路公司或者電商內部也已經大量使用 Netty 構建高效能、分散式的網路伺服器。遊戲行業:無論是手遊服務端、還是大型的網路遊戲,Java 語言得到了越來越廣泛的應用。Netty 作為高效能的基礎通訊元件,它本身提供了 TCP/UDP 和 HTTP 協議棧,非常方便定製和開發私有協議棧。賬號登陸伺服器、地圖伺服器之間可以方便的通過 Netty 進行高效能的通訊。
Netty 在遊戲伺服器架構中的應用大資料領域:經典的 Hadoop 的高效能通訊和序列化元件 Avro 的 RPC 框架,預設採用 Netty 進行跨節點通訊,它的 Netty Service 基於 Netty 框架二次封裝實現。大資料計算往往採用多個計算節點和一個/N個彙總節點進行分散式部署,各節點之間存在海量的資料交換。由於 Netty 的綜合效能是目前各個成熟 NIO 框架中最高的,因此,往往會被選中用作大資料各節點間的通訊。企業軟體:企業和 IT 整合需要 ESB,Netty 對多協議支援、私有協議定製的簡潔性和高效能是 ESB RPC 框架的首選通訊元件。事實上,很多企業匯流排廠商會選擇 Netty 作為基礎通訊元件,用於企業的 IT 整合。通訊行業:Netty 的非同步高效能、高可靠性和高成熟度的優點,使它在通訊行業得到了大量的應用
三.netty其他特點
設計
-
統一的 API,適用於不同的協議(阻塞和非阻塞)
-
基於靈活、可擴充套件的事件驅動模型
-
高度可定製的執行緒模型
-
可靠的無連線資料 Socket 支援(UDP)
效能
-
更好的吞吐量,低延遲
-
更省資源
-
儘量減少不必要的記憶體拷貝
安全
-
完整的 SSL/TLS 和 STARTTLS 的支援
易用
-
完善的 Java doc,使用者指南和樣例,社群很活躍
-
簡潔簡單
-
僅依賴於 JDK1.5
Netty框架
核心部分
-
零拷貝
“Zero-copy” describes computer operations in which the CPU does not perform the task of copying data from one memory area to another.
上面是 wiki 的一描述,它通常是指計算機在網路上傳送檔案時,不需要將檔案內容拷貝到使用者空間(User Space)而直接在核心空間(Kernel Space)中傳輸到網路的方式,所謂的兩個空間只是說明兩個不一樣的記憶體區域,通過減少不同記憶體區域的拷貝,減低 CPU 的消耗。下面有兩張對比圖:
1、非零拷貝模式
2、零拷貝模式
Netty 的零拷貝與實際定義還是有點出入,Java 是基於虛擬機器的,其實都是使用者空間,Netty 中的零拷貝,更多的是一種資料的優化操作,比如多包合併處理上,Netty是將各個包的地址記錄下來,在邏輯上合成一個整體,實際儲存還是獨立的,這樣減少記憶體拷貝,降低 CPU 消耗。
-
統一通訊 API
Netty 提供了命名為 channel 統一非同步 IO 介面,主要是為了解決 Java OIO , NIO API 不相容,簡化業務層的工作。
-
可擴充套件的事件模型
Netty has a well-defined event model focused on I/O. It also allows you to implement your own event type without breaking the existing code because each event type is distinguished from another by a strict type hierarchy. This is another differentiator against other frameworks.
Netty 是通過 ChannelEvent 作為事件流載體,通過 ChannelHander 來做事件邏輯處理,channelHander 又可分為 INBoundHandler 和 OUTBoundHandler 分別處理流入資料和流出資料,Event 則通過 sendDownStream 和 sendUpStream 在每個 handler 中流轉,ChannelPipeline 作為 handler 的容器,使用者自定義的 handler 只要新增到 pipe,就可以擷取資料流做業務處理。
所有的資料流轉,和執行過程都是在一個執行緒(EventLoop)上執行的,這種序列化的處理方式,讓 Netty 無鎖化,無需處理資料競爭問題,提高了執行效率。
高階元件
-
編解碼框架
Netty 提供裡提供一套 EncodeHandler 和 DecodeHandler,將業務邏輯從編解碼分離,大家可以瞭解一下,有時間會對這塊仔細說明
-
SSL/TLS Support
在 Netty 中使用 SSL 也是很方便的,使用 SSLEngine,SslHandler 就可以
-
Http/WebSocket 支援
Netty執行緒模型
Netty 支援三種執行緒模型,分別是單執行緒模型,多執行緒模型,以及主從執行緒模型,重點會介紹主從多執行緒模型
-
單執行緒模型
從 accpet 連線到分發到 handler 處理業務,都在單執行緒中完成,模型簡單,適合簡單場景,不適合大併發場景。
-
多執行緒模型
-
Acceptor 單獨執行緒接受 accpet 連線請求,建立 Channel,並移交給 IO 執行緒池
-
IO 執行緒池分配執行緒讀取 Channel 資料,並分發 handler 處理相關業務
-
Accpetor 是單執行緒,如果期間執行鑑權,登陸等操作,出現擁堵,會有單點問題。
-
主從多執行緒模型
-
Acceptor 執行緒池(NioEventLoopGroup)分配一個 NioEventLoop 接受連線請求,並建立 Channel,並將 Channel 移交給 IO 執行緒池
-
I/O 執行緒池((NioEventLoopGroup)分配一個 NioEventLoop 處理 Channel 資料,從 Channel 讀資料,並將資料交給 handler 處理,handler 處理完後,向 Channel 寫資料
-
I/O 執行緒池還可以處理定時任務,和系統任務。
這邊多次提到 NioEventLoop,許多個 NioEventLoop 構成 NioEventLoopGroup,其主要的職能如下:
作為 Acceptor 執行緒,負責處理客戶端的請求接入
作為 Connecor 執行緒,負責註冊監聽連線操作位,用於判斷非同步連線結果
作為 IO 執行緒,監聽網路讀操作位,負責從 SocketChannel 中讀取寫報文
這張圖很好的說明 NioEventLoop 的作用,以及 Netty 序列化的處理鏈。
-
一個客戶端 Channel 只能由一個 NioEventLoop 處理,避免併發資源競爭問題。
-
NioEventLoop 的事件是分發給 Netty 的事件模型,這個模型可以參考上面的說明。
總結
本文主要介紹了 Netty 的原理,重點對 Netty 的序列化處理鏈,執行緒模型,資料模型做了說明,繞過了細節,希望對大家在大層面去理解 Netty 有幫助,更多的實踐,以及細節,留在後續文章再說。
相關文章
- Netty1:初識NettyNetty
- Springboot 整合 Netty 實戰Spring BootNetty
- netty實戰之二 helloNettyNetty
- 一、初識NettyNetty
- 《Netty實戰》-學習筆記1Netty筆記
- 認真的 Netty 原始碼解析(二)Netty原始碼
- 認真的 Netty 原始碼解析(一)Netty原始碼
- Netty知識點(雜記)Netty
- Netty FastThreadLocal 實踐NettyASTthread
- netty系列之:netty初探Netty
- Netty series: handling CORS in nettyNettyCORS
- netty系列之:Bootstrap,ServerBootstrap和netty中的實現NettybootServer
- netty系列之:EventExecutor,EventExecutorGroup和netty中的實現Netty
- netty系列之:channel,ServerChannel和netty中的實現NettyServer
- netty系列之:EventLoop,EventLoopGroup和netty的預設實現NettyOOP
- 初識Netty原理(一)—— 基本使用Netty
- Netty高階應用及聊天室實戰Netty
- Netty實現Web SocketNettyWeb
- nettyNetty
- netty系列之:netty架構概述Netty架構
- netty系列之:netty實現http2中的流控制NettyHTTP
- Netty原始碼分析(七):初識ChannelPipelineNetty原始碼
- netty學習(三)springboot+netty+mybatisNettySpring BootMyBatis
- Netty原始碼分析(一):Netty總覽Netty原始碼
- netty系列之:NIO和netty詳解Netty
- Netty 原始碼分析系列(一)Netty 概述Netty原始碼
- netty系列之:netty對marshalling的支援Netty
- Netty教程Netty
- Netty:ChannelFutureNetty
- 網路應用扛把子Netty!騰訊高工手寫“Netty速成手冊”,3天帶你走向實戰Netty
- netty系列之:在netty中實現執行緒和CPU繫結Netty執行緒
- 聊聊 Netty 那些事兒之 Reactor 在 Netty 中的實現(建立篇)NettyReact
- netty系列之:使用netty實現支援http2的伺服器NettyHTTP伺服器
- netty系列之:netty中的Channel詳解Netty
- netty系列之:netty中的ByteBuf詳解Netty
- Netty 框架學習 —— Netty 元件與設計Netty框架元件
- netty系列之:在netty中使用proxy protocolNettyProtocol
- netty系列之:在netty中處理CORSNettyCORS