Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
在看微博開源的rpc框架motan的過程中,了解到其使用了Netty構建客戶和服務端,為了理解motan的源碼于是找了Netty的相關書籍,其中之一就是《Netty In Action》,該書作者之一就是Netty的主力開發人員之一Norman Maurer。
書主要分為四個部分:
- Netty概念和架構:提供了簡單點示例,介紹了組件及其設計和架構
- Codecs:詳細介紹了編碼和解碼的實現
- 網絡協議:WebSocket和UDP
- 案例研究:Droply, Firebase, Urban Airship, Nifty, Swift和Fiangle
讀完全書,對于Netty有了個基本的了解,可以嘗試用其開發異步的網絡服務例如企業自己的rpc框架,或者提供一些異步的高性能服務。
接下來把書中的內容做個梳理和介紹。
組件和架構
Netty組件包括如下幾個類型:
- Channel: 通道,表示到一些實體例如網絡socket和文件的連接,通過它能執行I/O操作,比如讀和寫。生命周期中狀態轉換依次為:Unregistered (已創建未和注冊到EventLoop),Registered(注冊到EventLoop),Active(已連接到遠程,可以接收和發送數據)和Inactive(斷開連接)。
A Channel is a basic construct of Java NIO, it represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.
- EventLoop & EventLoopGroup:一個EventLoopGroup包含一個或多個EventLoop,EventLoop通過一個線程處理所有的I/O事件,其被委派給一個或者多個Channel,一個Channel在其生命周期內只注冊到一個的EventLoop。
https://en.wikipedia.org/wiki/Event_loop: the event loop, message dispatcher, message loop, message pump, or run loop is a programming construct that waits for and dispatches events or messages in a program.
ChannelFuture:注冊監聽器到異步的I/O操作,操作完成時監聽器將被通知到。
ChannelHandler & ChannelHandlerContext:處理進入和輸出的數據,有多種類型的handler。
ChannelPipeline:每一個Channel都會關聯到一個ChannelPipeline,一個Channel一個ChannelPipeline其包含多個ChannelHandler,一個事件經過pipeline時里面所有的handler都會被按照加入順序執行來處理事件。
BootStrap and ServerBootStrap:Bootstrap用來連接遠程主機,有1個EventLoopGroup;ServerBootstrap用來綁定本地端口,有2個EventLoopGroup:一個與server自己的監聽socket關聯,對于所有進入的request創建channel,一個用來處理創建好的channel,分派EventLoop給channel。
一些功能
ByteBuf - Netty的數據容器
數據容器,用于數據的讀寫,ByteBuf有兩種使用模式:堆緩沖區(HEAP BUFFERS:copy and write),直接緩沖(DIRECT BUFFER:zero copy)和組合緩沖(COMPOSITE BUFFERS: aggregate to avoid concating by copying multiple buffers),第一種在JVM的堆存儲數據,第二種是在堆外存儲,最后一種是在聚合多個不同的ByteBuff。Netty提供了allocator分配池化的ByteBuf以便更好的利用內存,同時也提供了非池化的實現。
編解碼(Codec)
Codec組件包括encoder和decoder,是Netty的一個重要組成部分,用來做數據轉換在網絡傳輸和應用數據,重用比如有ByteToMessageDecoder,MessageToMessageDecoder,MessageToByteEncoder,MessageToMessageEncoder或ByteToMessageCodec和MessageToMessageCodec其同時包含decode和encode。Codec是pipeline的一部分,與其他handler一起順序執行,例如對于輸入的數據先decode然后送到后續的handler。
安全
- SSL/TSL/HTTPS:利用SslHandler,SslEngine和SSLEngine來加密和解密數據。
傳輸和不同協議的支持
- WebSocket
- UDP
- MQTT
- Protocol Buffer
- Thrift
具體實現和案例
客戶端實現注意事項
- Channel的長鏈接和重用?例如像motan用apache的object pool緩存channel
- 如何配置和發現服務?ZooKeeper或Consul或者其他?
- 心跳實現?
- 數據傳輸的安全性?
服務端實現注意事項
- 如何注冊服務?ZooKeeper或Consul或者其他?
- 使用線程池來處理request
- 降級開關
- 調用統計和監控
motan是一個很好的參看,架構清晰,代碼模塊化,簡單明了和測試也比較全面。