原文鏈接:http://xueliang.org/article/detail/20200712234015993
前言
在Netty的執行緒模型中,對于一個TCP連接的讀寫操作,都是由一個單執行緒完成的,對于剛入門Netty的新手,這完全顛覆我們熟知的多執行緒能夠加快處理速度,縮短處理時間的常規思路,
實際上,Netty采用了異步通信模式,一個IO 執行緒可以并發處理N 個客戶端連接和讀寫操作,這從根本上解決了傳統同步阻塞IO 一連接一執行緒模型,架構的性能、彈性伸縮能力和可靠性都得到了極大的提升,
原始碼閱讀
將 Channel 注冊到 Worker 執行緒組上
呼叫 NioEventLoopGroup 的 next() 從 Worker 執行緒組中獲取一個 eventLoop
根據執行緒組個數不同,會呼叫 PowerOfTwoEventExecutorChooser 或者 GenericEventExecutorChooser 的 next() 方法,如果執行緒數是 2 的 N 次方,就選用 PowerOfTwoEventExecutorChooser 這個 EventLoop 選擇類,使用位運算提高效率
呼叫選取的 eventLoop 的 register() 方法,可以看到,將 this 也就是當前 EventLoop 當做引數傳入 promise.channel().unsafe().register() 方法
繼續進到 promise.channel().unsafe().register 方法,到這里,終于將 eventLoop 賦值給了 Channel,即 Channel 與 eventLoop 建立了系結關系,
但Channel還未與執行緒系結,繼續往下看,當我們平時在Handler里呼叫 ctx (即 ChannelHandlerContext 類物件)的 write() 時,實際是獲取 ctx 的 executor 執行寫操縱事件,若未給 ctx 指定 executor,則 ctx 會使用 對應的 channel 的 eventLoop
執行 eventLoop 的 execute() 方法
進到 execute() 方法內,先通過呼叫 inEventLoop() 方法,判斷當前執行緒是否是 eventLoop 系結的那個執行緒
如果不是,則可能 eventLoop 還沒有系結執行緒,則呼叫 startThread 方法創建一個執行緒
最終呼叫 eventLoop 的 doStartThread() ,由 executor 指定創建執行緒的任務,
到此,Channel - EventLoop - Thread 系結在了一起,同時也能看出多個 Channel 可能系結到 一個EventLoop上
總結
Netty將一個TCP連接和一個固定的執行緒系結,不需要進行執行緒切換以及執行緒同步,即節省資源又提高吞吐效率,除此之外我們在閱讀原始碼的程序中,從EventLoop的選取,根據不同的執行緒數,使用不同的輪詢器,可以看出Netty對于高性能的極致追求,
原文鏈接:http://xueliang.org/article/detail/20200712234015993
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/142946.html
標籤:Java
上一篇:linux下安裝ffmpeg
