[TOC]
在前面的章節中,我們學會了使用Java NIO進行長連接Server的開發。盡管NIO在通訊過程中有內存占用低等優點,但其在配置使用方面,沒有框架提供的功能便捷。接下來,我們將學習使用流行的Socket通信框架,來實現長連接服務端的開發。
Server端建議使用框架:
- Netty
- Mina
- QuickServer
## Netty簡介
Netty作為一個高性能的NIO通信框架,它的健壯性、功能、性能、可定制性和可擴展性在同類框架中都是首屈一指的,已經得到了成百上千的商用項目驗證。
> 面對新事物的時候,人們往往把它想得太難,拿起來看看,才知道它是咋般模樣。
相比同步I/O簡單直接的編程模型,異步I/O在編程模型上有較大的差異,對開發人員也有更高的要求,同時問題的定位也更為復雜。Netty是當前業界應用最廣泛的Java開源異步框架。Netty 框架能顯著降低異步開發的門檻,使開發人員聚焦業務邏輯,免于處理復雜的底層通信機制和線程模型,從而能夠簡單和快速地開發異步應用。時至今日,越來越多的國內公司開始使用Netty來構建應用,使用Netty的開發者也日益增加。
### Netty的體系結構

看下一下上面的這張圖,概述了Netty的一些核心能力:
- 傳輸服務支持NIO、BIO;
- 協議支持HTTP、Google Protobuf、文本行、二進制、視頻圖像等;
- 提供了OOM-Proof Thread Pool、SSL安全支持
- 支持Spring等容器的集成
- 其核心特征:可擴展的事件模型、統一的對接API、零拷貝能力的Byte Buffer。
## 核心類
在使用 Netty 進行服務端程序開發時,主要涉及端口監聽、EventLoop 線程池創建、NioServerSocketChannel 和 ChannelPipeline 初始化等。
### channel
channel的主要作用:
- close(),關閉channel
- closeFuture()用來處理channel的關閉
- sync(),同步等待channel關閉
- addListener(),異步等待channel關閉
- pipeline(),添加處理器
- write(),將數據寫入channel,需要配合flush()才能將數據刷出
- writeAndFlush(),將數據寫入并刷出
### pipeline&handler
> 顧名思義,pipeline是一條處理消息的流水線,每一條工序,都在pipeline中進行了定義。
ChannelHandler用來處理Channel上的業務事件,pipeline則把各種ChannelHandler連成一串。

在Reactor經典模型中,Reactor查詢到NIO就緒的事件后,分發到Handler,由Handler完成NIO操作和計算的操作。Handler主要的操作為Channel緩存讀、數據解碼、業務處理、寫Channel緩存,然后由Channel(代表client)發送到最終的連接終端。ChannelHandler分為兩類:
- 入站處理器(ChannelInboundHandlerAdapter):主要用來讀取客戶端數據
- 出戰處理器(ChannelInboundHandlerAdapter):主要翻來對返回客戶端的數據進加工
注意點:
- pipeline中的入站處理器沒有向channel中寫入數據,出站處理器是不會被觸發的。
- 前面的入站處理器需要調用`super.channelRead(ctx, msg)`或者`ctc.fireChannelRead(msg)`,消息才能向后方的入站處理器傳遞——所謂,“擊鼓傳花,不能有人偷懶”;
- ChannelHandler的執行順序:ChannelInboundHandlerAdapter是按添加順序,ChannelInboundHandlerAdapter則與添加順序相反。

#### `channel.writeAndFlush()`和`ctx.writeAndFlush()`區別
- `ctx.writeAndFlush()`,是從當前的handler,由后向前找出站處理器;
- `channel.writeAndFlush()`,是從pipeline尾部開始,由后向前找出站處理器。
### 關于深入學習
由于篇幅原因,本小冊側重于實際項目演練,關于深入學習Netty一些方法,大家供可以參考一下。
- 使用Netty開發基本網絡應用程序
- 徹底理解阻塞、非阻塞的區別,并跟Netty、 NIO的編碼聯系起來
- 懂得多路復用在服務器開發時的優勢,為什么在此基礎上還要加多線程
- Netty中是如何實現異步的,異步處理的優勢是什么
- Netty中是如何管理線程的,EventLoop 如何運作
- Netty中是如何管理內存的,ByteBuf特點和分配時機
- 看源碼、調試的一些技巧,讓自己也能去看、去跟源碼
- 第一章 開篇寄語
- 1-1 技術選型要點
- 1-2 認識905.4王國的交流規范
- 1-3 聯系作者
- 第二章 Socket編程的基礎知識
- 2-1 Socket家族的基石
- 2-2 byte數組基礎
- 2-3 緩沖區基礎
- 2-4 NIO Socket通訊的工作原理
- 第三章 905.4規范解讀
- 3-1 基于通道選擇器的Socket長連接及消息讀寫框架
- 3-2 嚴格的信件收發員
- 3-3 負責消息處理的一家子
- 3-4 負責認證的大兒子(AuthWorker)
- 3-5 啞巴老二(PingWoker)
- 3-6 勤奮的定位匯報員老三(LocationReportWorker)
- 3-7 精明的老四(BusinessReportWorker)
- 3-8 數據檢察官——CRC16-CCITT校驗
- 3-11 數據的加密官
- 3-12 頭尾標識轉義
- 第四章 測試方法
- 4-1 測試數據樣例
- 4-2 客戶端鏈路保持功能實現
- 4-3 使用Socket短連接進行功能測試
- 4-4 NIO服務端性能分析
- 4-5 http測試方法(推薦)
- 第五章 從NIO到netty
- 5-1 編程進階——Netty核心基礎
- 5-2 Netty使用常見問題
- 5-3 使用Netty重寫Server端
- 5-4 Netty之鏈路管理
- 5-5 netty堆外內存泄漏如何應對?
- 第六章 統計與監控
- 6-1 Grafana監控面板
- 第七章 售后服務
- 7-1 勘誤與優化
- 7-2 獲取源碼