Netty 的使用一個包含 EventLoop 的 EventLoopGroup 為 Channel 的 I/O 和事件服務。EventLoop 創建并分配方式不同基于傳輸的實現。異步實現使用只有少數 EventLoop(和 Threads)共享于 Channel 之間 。這允許最小線程數服務多個 Channel,不需要為他們每個人都有一個專門的 Thread。
圖15.7顯示了如何使用 EventLoopGroup。
[.jpg)](https://github.com/waylau/essential-netty-in-action/blob/master/images/Figure%2015.7%20Thread%20allocation%20for%20nonblocking%20transports%20(such%20as%20NIO%20and%20AIO).jpg)
1. 所有的 EventLoop 由 EventLoopGroup 分配。這里它將使用三個EventLoop 實例
2. 這個 EventLoop 處理所有分配給它管道的事件和任務。每個EventLoop 綁定到一個 Thread
3. 管道綁定到 EventLoop,所以所有操作總是被同一個線程在 Channel 的生命周期執行。一個管道屬于一個連接
Figure 15.7 Thread allocation for nonblocking transports (such as NIO and AIO)
如圖所述,使用有 3個 EventLoop (每個都有一個 Thread ) EventLoopGroup 。EventLoop (同時也是 Thread )直接當 EventLoopGroup 創建時分配。這樣保證資源是可以使用的
這三個 EventLoop 實例將會分配給每個新創建的 Channel。這是通過EventLoopGroup 實現,管理 EventLoop 實例。實際實現會照顧所有EventLoop 實例上均勻的創建 Channel (同樣是不同的 Thread)。
一旦 Channel 是分配給一個 EventLoop,它將使用這個 EventLoop 在它的生命周期里和同樣的線程。你可以,也應該,依靠這個,因為它可以確保你不需要擔心同步(包括線程安全、可見性和同步)在你 ChannelHandler實現。
但是這也會影響使用 ThreadLocal,例如,經常使用的應用程序。因為一個EventLoop 通常影響多個 Channel,ThreadLocal 將相同的 Channel 分配給 EventLoop。因此,它適合狀態跟蹤等等。它仍然可以用于共享重或昂貴的對象之間的 Channel ,不再需要保持狀態,因此它可以用于每個事件,而不需要依賴于先前 ThreadLocal 的狀態。
*EventLoop 和 Channel*
*我們應該注意,在 Netty 4 , Channel 可能從 EventLoop 注銷稍后又從不同 EventLoop 注冊。這個功能是不贊成,因為它在實踐中沒有很好的工作*
語義跟其他傳輸略有不同,如 OIO(Old Blocking I/O)運輸,可以看到如圖14.8所示。
[.jpg)](https://github.com/waylau/essential-netty-in-action/blob/master/images/Figure%2015.8%20Thread%20allocation%20of%20blocking%20transports%20(such%20as%20OIO).jpg)
1. 所有 EventLoop 從 EventLoopGroup 分配。每個新的 channel 將會獲得新的 EventLoop
2. EventLoop 分配給 channel 用于執行所有事件和任務
3. Channel 綁定到 EventLoop。一個 channel 屬于一個連接
Figure 15.8 Thread allocation of blocking transports (such as OIO)
你可能會注意到這里,一個 EventLoop (也是一個 Thread)創建每個 Channel。你可能被用來從開發網絡應用程序是基于常規阻塞I/O在使用java.io.* 包。但即使語義變化在這種情況下,有一件事仍然是相同的:每個 I/O 通道將由一次只有一個線程來處理,這是一個線程增強 Channel 的 EventLoop。可以依靠這個硬性的規則,使 Netty 的框架很容易與其他網絡框架進行比較。
- Introduction
- 開始
- Netty-異步和數據驅動
- Netty 介紹
- 構成部分
- 關于本書
- 第一個 Netty 應用
- 設置開發環境
- Netty 客戶端/服務端 總覽
- 寫一個 echo 服務器
- 寫一個 echo 客戶端
- 編譯和運行 Echo 服務器和客戶端
- 總結
- Netty 總覽
- Netty 快速入門
- Channel, Event 和 I/O
- 什么是 Bootstrapping 為什么要用
- ChannelHandler 和 ChannelPipeline
- 近距離觀察 ChannelHandler
- 總結
- 核心功能
- Transport(傳輸)
- 案例研究:Transport 的遷移
- Transport API
- 包含的 Transport
- Transport 使用情況
- 總結
- Buffer(緩沖)
- Buffer API
- ByteBuf - 字節數據的容器
- 字節級別的操作
- ByteBufHolder
- ByteBuf 分配
- 總結
- ChannelHandler 和 ChannelPipeline
- ChannelHandler 家族
- ChannelPipeline
- ChannelHandlerContext
- 總結
- Codec 框架
- 什么是 Codec
- Decoder(解碼器)
- Encoder(編碼器)
- 抽象 Codec(編解碼器)類
- 總結
- 提供了的 ChannelHandler 和 Codec
- 使用 SSL/TLS 加密 Netty 程序
- 構建 Netty HTTP/HTTPS 應用
- 空閑連接以及超時
- 解碼分隔符和基于長度的協議
- 編寫大型數據
- 序列化數據
- 總結
- Bootstrap 類型
- 引導客戶端和無連接協議
- 引導服務器
- 從 Channel 引導客戶端
- 在一個引導中添加多個 ChannelHandler
- 使用Netty 的 ChannelOption 和屬性
- 關閉之前已經引導的客戶端或服務器
- 總結
- 引導
- Bootstrap 類型
- 引導客戶端和無連接協議
- 引導服務器
- 從 Channel 引導客戶端
- 在一個引導中添加多個 ChannelHandler
- 使用Netty 的 ChannelOption 和屬性
- 關閉之前已經引導的客戶端或服務器
- 總結
- NETTY BY EXAMPLE
- 單元測試
- 總覽
- 測試 ChannelHandler
- 測試異常處理
- 總結
- WebSocket
- WebSocket 程序示例
- 添加 WebSocket 支持
- 測試程序
- 總結
- SPDY
- SPDY 背景
- 示例程序
- 實現
- 啟動 SpdyServer 并測試
- 總結
- 通過 UDP 廣播事件
- UDP 基礎
- UDP 廣播
- UDP 示例
- EventLog 的 POJO
- 寫廣播器
- 寫監視器
- 運行 LogEventBroadcaster 和 LogEventMonitor
- 總結
- 高級主題
- 實現自定義的編解碼器
- 編解碼器的范圍
- 實現 Memcached 編解碼器
- 了解 Memcached 二進制協議
- Netty 編碼器和解碼器
- 測試編解碼器
- EventLoop 和線程模型
- 線程模型的總覽
- EventLoop
- EventLoop
- I/O EventLoop/Thread 分配細節
- 總結
- 用例1:Droplr Firebase 和 Urban Airship
- 用例2:Facebook 和 Twitter