解讀netty3.9的數據處理流程(一)


前言:git

Netty是一個異步事件驅動的網絡應用程序框架用於快速開發可維護的高性能協議服務器和客戶端。github

特色:
bash

  • 統一的API,適用於不一樣的協議(阻塞和非阻塞)服務器

  • 基於靈活、可擴展的事件驅動模型網絡

  • 高度可定製的線程模型框架

環境準備:

拉取 https://github.com/netty/netty/tree/3.9異步

命令:
源碼分析

git clone https://github.com/netty/netty.gitGit checkout -b 3.9 origin/3.9
Git checkout -b 3.9 origin/3.9
複製代碼

netty概覽:性能

在netty中,Channel是通信的載體,ChannelHandler是數據處理的執行者,ChannelPipeline是數據處理的通道;ui

                 

數據流向分析:

DefaultChannelPipeline爲例,講述已註冊到管道pipeline的ChannelHandler如何處理數據?


downStream方向 :業務對象 =》 數據流

從pipeline管道tail對象起依次調用註冊的ChannelDownstreamHandler處理器,最終經由ChannelSinkeventSunk根據事件觸發boss或者worker線程池處理任務。


upStream方向 :數據流 =》 業務對象

從pipeline管道head對象開始依次調用註冊的ChannelUpstreamHandler處理器,最終將數據流轉爲業務層的業務對象。

這點很重要,會影響到咱們註冊處理器的邏輯。


對於ChannelSink如何真正地觸發數據寫出去?暫僅考慮MessageEvent,能夠看到將消息寫到channel所在worker線程的隊列中,並調用writeFromUserCode觸發worker發送數據。


寫模型:

對於存在隊列中的數據如何依次發送呢?若是不可寫了該怎麼處理?(寫入過快來不及發送,致使緩衝區滿了)


能夠看到依次處理隊列中的消息,若是有消息,則調用buf.transferTo(ch)將數據發送出去,若是返回localWrittenBytes大於0,跳出本次循環,如爲零則循環writeSpinCount,如再次期間localWrittenBytes>0,說明再次可寫。並調用fireWriteComplete觸發上游,這裏暫時忽略結果處理。

說明:觸發寫不止這種狀況,channel可寫的狀況下也會觸發將隊列清空。

讀模型分析:

寫的流程已經分析完成,讀模型相對簡單,當監聽到讀事件時,即會觸發worker讀取數據裝載成buffer,調用handler處理。


後續:

後續會先對Netty特性基於源碼分析,並設計個便捷可配置的壓測模型,方便開發中快速針對不一樣通信實現壓測。

能夠點擊閱讀原文獲取《Nip trick and trip》,相信能夠使得netty的理解更深刻。


喜歡的讀者能夠關注路上小棧,及時獲取最新的技術文章,專一源碼分析、技術業務思考等。

相關文章
相關標籤/搜索