1. Channel
Channel是Netty的核心概念之一,它是Netty網絡通信的主體,由它負責同對端進行網絡通信、注冊和數據操作等功能。
1.1 工作原理
如上圖所示:
- 一旦用戶端連接成功,將新建一個channel同該用戶端進行綁定
- channel從EventLoopGroup獲得一個EventLoop,並注冊到該EventLoop,channel生命周期內都和該EventLoop在一起(注冊時獲得selectionKey)
- channel同用戶端進行網絡連接、關閉和讀寫,生成相對應的event(改變selectinKey信息),觸發eventloop調度線程進行執行
- 如果是讀事件,執行線程調度pipeline來處理用戶業務邏輯
1.2 狀態轉換
如上圖所示,Channel包含注冊、活躍、非活躍和非注冊狀態,在一般情況下是從注冊->活躍->非活躍->非注冊,但用戶可以從eventloop取消和重注冊channel,因此在此情況下活躍->非注冊->注冊
1.3 線程
多個channel可以注冊到一個eventloop上,所有的操作都是順序執行的,eventloop會依據channel的事件調用channel的方法進行相關操作,每個channel的操作和處理在eventloop中都是順序的,如下圖:
2. ChannelPipeline和ChannelHandler
ChannelPipeline和ChannelHandler用於channel事件的攔截和處理,Netty使用類似責任鏈的模式來設計ChannelPipeline和ChannelHandler
ChannelPipeline相當於ChannelHandler的容器,channel事件消息在ChannelPipeline中流動和傳播,相應的事件能夠被ChannelHandler攔截處理、傳遞、忽略或者終止,如下圖所示:
2.1 INBOUD和OUTBOUND事件
inbound:當發生某個I/O操作時由IO線程流向用戶業務處理線程的事件,如鏈路建立、鏈路關閉或者讀完成等
outbound:由用戶線程或者代碼發起的IO操作事件
2.2 ChannelHandlerContext
每個ChannelHandler 被添加到ChannelPipeline 后,都會創建一個ChannelHandlerContext 並與之創建的ChannelHandler 關聯綁定。如下圖:
ChannelHandler通過ChannelHandlerContext來操作channel和channelpipeline
2.3 ChannelHandler
ChannelHandler負責I/O事件或者I/O操作進行攔截和處理,用戶可以通過ChannelHandlerAdapter來選擇性的實現自己感興趣的事件攔截和處理。
由於Channel只負責實際的I/O操作,因此數據的編解碼和實際處理都需要通過ChannelHandler進行處理。
2.4 注意
ChannelPipeline是線程安全的,多個業務線程可以並發的操作ChannelPipeline;ChannelHandler不是線程安全的,用戶需要自己保重ChannelHandler的線程安全
3. ChannelFuture與ChannelPromise
在Netty中,所有的I/O操作都是異步的,因此調用一個I/O操作后,將繼續當前線程的執行,但I/O操作的結果怎么獲得?——ChannelFuture。
如上圖,當前線程A異步發起I/O操作后,不阻塞繼續執行相關操作,當IO線程B完成后,通過回調執行A設置的回調方法。
回調方法通過監聽的形式實現:ChannelFutureListener。
ChannelPromise是ChannelFuture的擴展,允許設置I/O操作的結果,使ChannelFutureListener可以執行相關操作