【圖解IO與Netty系列】Reactor模型

Reactor模型

  • Reactor模型簡介
    • 三類事件與三類角色
    • Reactor模型整體流程
  • 各種Reactor模型
    • 單Reactor單線程模型
    • 單Reactor多線程模型
    • 主從Reactor模型

Reactor模型簡介

Reactor模型是服務器端用于處理高并發網絡IO請求的編程模型,與傳統的一請求一線程的同步式編程模型不同的是,Reactor模型是基于事件驅動的響應式編程模型,可以一個線程處理多個請求,并且是異步處理,在高并發場景下,性能大大的提升。

傳統的同步式編程模型如下:

在這里插入圖片描述

服務端接收到請求后,從線程池中拿出一個線程(比如Tomcat里的線程池),經過Controller、Service、Dao的一頓處理,最后返回響應結果給客戶端。這種同步處理請求的方式效率并不高,可以應對一些并發量不高的場景。

基于事件驅動的響應式編程模型如下:
在這里插入圖片描述

  1. 服務端啟動時,會創建Reactor反應器,然后會向Reactor注冊基本的事件類型與對應的Handler(比如網絡編程時的連接就緒事件與Acceptor)
  2. 當服務端接收到客戶端的請求時,服務端的Reactor就有事件就緒,Reactor會獲取到就緒的事件,在高并發場景下,Reactor有可能獲取到一批就緒的事件
  3. Reactor進事件分發,把事件分派給與之綁定的Handler中,Handler對事件的處理可以在當前線程中也可以在線程池中,當然在線程池中處理性能會更高
  4. Handler處理完畢后,如果后續還有其他處理步驟,則可以繼續注冊新的事件與對應的Handler到Reactor中;如果沒有后續,則可以返回響應結果給客戶端,返回響應結果這個動作可作為單獨的一個事件,由對應的Handler進行處理,那么也可以繼續注冊到Reactor中。

Reactor其實就是一個線程,可以看到它就在一個死循環中進行事件監聽以及事件分派,這就是事件循環。

Reactor模型底層使用了IO多路復用,通過對IO多路復用機制的合理利用,使得服務器端達到高效的處理網絡IO請求的目的。我們可以使用Java提供的NIO來實現Java版本的Reactor模型。
在這里插入圖片描述

三類事件與三類角色

Reactor模型抽象了三類事件和三類角色,它們是Reactor模型的核心組成部分。三類事件是:連接就緒事件,讀就緒事件、寫就緒事件。三類角色是:Reactor、Acceptor、Handler。

首先我們來了解一下三類事件。

在這里插入圖片描述

  • 連接就緒事件:客戶端向服務端發起連接的時候,對應的Channel就有連接就緒事件發生。
  • 讀就緒事件:當客戶端向服務器端發送數據時,對應的Channel就有讀就緒事件發生。
  • 寫就緒事件:當服務器處理完客戶端發送的數據,需要返回結果時,可以向Selector注冊一個寫就緒事件并與對應的Channel關聯,那么對應Channel就有寫就緒事件發生。

我們再來了解一下三類角色。
在這里插入圖片描述

Reactor是相當于是一個事件分派器,Reactor專門負責監聽事件的發生,并把發生的事件交給對應的處理器處理,這里的處理器指的就是Acceptor或Handler。Reactor是一個線程,它通過Selector注冊并監聽多個Channel,如果監聽到有事件發生,判斷是連接就緒事件,會交給Acceptor處理,如果發生的事件是讀就緒事件或寫就緒事件,會交給Handler處理。

在這里插入圖片描述

如果是連接就緒事件,Reactor會將其分派給Acceptor處理,Acceptor會調用accept()方法獲取到連接對應的SocketChannel,然后會將其設置為非阻塞,注冊到Reactor的Selector中,設置關注的事件為讀就緒事件。

在這里插入圖片描述

如果是讀就緒事件,那么Reactor會將其分派給與其綁定的Handler處理,該Handler會經過read、decode、compute、encode、send五個步驟的處理。

  1. read:讀取Channel中的數據
  2. decode:對讀到的數據進行解碼
  3. compute:解碼后的數據進行相應處理
  4. encode:對處理后的結果進行編碼
  5. send:編碼后的數據發送給客戶端。

之所以要進行decode和encode,是因為數據在網絡上是以二進制的形式傳輸的,因此服務端接收到后要對二進制字節碼進行解碼操作,然后才能對解碼后的數據進行處理,處理完的數據要發送到網絡,也要編碼成二進制的格式。

在這里插入圖片描述

其中,send操作可以立刻發送數據寫出到Channel,也可以注冊一個寫就緒事件到Selector,這就相當于進行異步發送。

在這里插入圖片描述

Reactor模型整體流程

在這里插入圖片描述

  1. 首先,一開始我們只把ServerSocketChannel以及連接事件處理器Acceptor注冊到Reactor中,Reactor會把ServerSocketChannel注冊到Selector中,并設置關注連接就緒事件
  2. 一旦客戶端發起連接,ServerSocketChannel的連接就緒事件就緒,Reactor會將其分派給Acceptor處理,Acceptor會獲取到連接對應的SocketChannel,并將其與對應的處理器Handler注冊到Reactor,Reactor會將其注冊到Selector中。
  3. 隨后客戶端向服務端發送數據,Reactor監聽到對應的SocketChannel有讀就緒事件發生,會將其分派給與其綁定的Handler進行處理。
  4. Handler被分派到讀就緒事件時,會經過read、decode、compute、encode、send五個步驟的處理。
  5. 服務端要把處理結果返回給客戶端,會向Reactor注冊一個對應Channel的寫就緒事件,Reactor監聽到寫就緒事件,會分派給與該Channel綁定的Handler處理,Handler把返回結果發送出去。

各種Reactor模型

Reactor編程模型不是只有單一的一種編程模型,它有單Reactor單線程模型、單Reactor多線程模型、主從Reactor模型等多種模型。

單Reactor單線程模型

單Reactor單線程模型是最簡單的模型,當然性能也是最低的。單Reactor模型只有一個Reactor,這個Reactor即負責處理連接建立,也負責數據讀寫和計算等處理。并且由于是單線程模型,所以數據讀取后的計算處理,也是在當前線程中完成。

在這里插入圖片描述

這種單Reactor單線程模型雖然性能比其他的Reactor模型低,但是優點是比較的簡單,沒有了多線程就意味著沒有了“多線程翻車”的一些情況出現。值得一提的是,Redis的事件驅動框架就是單Reactor單線程模型

但是由于連接建立與IO處理都在一個Reactor線程中進行,因此在高并發場景下,該Reactor線程的壓力會非常大,特別是在數據計算還比較復雜的場景,單線程的Reactor模型有可能支撐不住。之所以Redis使用單Reactor單線程模型還能支撐高并發讀寫的場景,其中一個原因是因為Redis內部不涉及太復雜的數據計算。

單Reactor多線程模型

單Reactor多線程模型是在單Reactor模型的基礎上增加了線程池,可以把decode、compute、encode等需要計算的操作提交到線程池執行,而Reactor線程則專注于連接建立與IO的處理(也就是read和send)。

在這里插入圖片描述

把涉及到計算的處理抽到了線程池中處理,可以在一定程度上緩解Reactor線程的壓力。但是由于還是單Reactor模型,IO處理依然在該Reactor線程中進行,高并發場景下,可能會由于大量的IO請求需要處理而導致連接建立的處理受到影響,該Reactor線程可能無法及時響應客戶端連接建立的請求。

主從Reactor模型

主從Reactor模型在單Reactor多線程模型基礎上做了改進,把IO處理分離到了子Reactor中,主Reactor只專注于連接請求的處理,主Reactor一般只有一個(也可有多個),而子Reactor一般有多個。當主Reactor上有連接就緒事件發生時,通過Acceptor獲取到連接對應的SocketChannel,然后把該SocketChannel注冊到子Reactor中,由子Reactor監聽該Channel的讀就緒事件并處理。

在這里插入圖片描述

由于連接建立與IO處理分離到了不同的Reactor,當有大量并發的IO請求需要處理時,也不會影響到客戶端建立連接的請求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20555.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20555.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20555.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

翼龍面板是什么,如何進行搭建

翼龍面板是一個開源的,用于游戲服務器管理的程序,可以方便地在網頁界面中創建Minecraft,起源引擎游戲和Teamspeak3 服務器。 它使用前后端程序,因此可以創建多后端節點,對游戲服務器和服務器節點進行統一管理。 對游戲…

Vue進階之Vue無代碼可視化項目(二)

Vue無代碼可視化項目 項目初始化路由子路由錯誤示范正確示范App.vuerouter/index.tsAboutView.vueAboutAboutview.vuerouter/index.ts項目路由router/index.tsApp.vueActionsView.vueDataSourceView.vueLayoutView.vue路由樣式App.vue進一步的App.vue項目初始化 路由 router i…

synchronized 鎖的到底是什么?

通過8種情況演示鎖運行案例,看看我們到底鎖的是什么 1鎖相關的8種案例演示code package com.bilibili.juc.lock;import java.util.concurrent.TimeUnit;/*** 題目:談談你對多線程鎖的理解,8鎖案例說明* 口訣:線程 操作 資源類* 8…

修改hostname導致RabbitMQ數據丟失

背景介紹 公司的很多關鍵服務都使用了RabbitMQ來作為消息隊列服務, 可以說是非常地關鍵的一個環節, 最近由于業務量的上升, 導致RabbitMQ的CPU持續走高, 所以抽空研究了一下RabbitMQ的擴容, 利用我們自己運維平臺使用的一個單節點的RabbitMQ來作為測試吧.看到這個單節點的Rabbi…

第十七節 huggingface的trainner的斷點續訓的Demo(resume)

文章目錄 前言一、參數決定權重保存1、model.safetensors保存2、scaler.pt保存3、optimizer.pt與scheduler.pt保存4、self.state狀態保存(trainer_state.json)5、rng_state.pth保存6、權重相關保存位置(huggingface)二、Resume的Demo1、Demo構建2、實現Resume方法三、Resume訓…

005 CentOS 7.9 RabbitMQ安裝及配置

https://github.com/rabbitmq/rabbitmq-server/releases https://www.rabbitmq.com/docs/download https://packagecloud.io/rabbitmq/rabbitmq-server https://www.erlang-solutions.com/downloads/ https://www.erlang.org/ 文章目錄 卸載erlerl版本安裝與下載版本不匹配正…

AI技術的深度探索:重塑未來的智能引擎

隨著科技的迅猛進步,人工智能(AI)技術已經逐漸滲透到我們生活的每一個角落,從簡單的智能助手到復雜的決策支持系統,AI技術以其獨特的方式和前所未有的速度改變著我們的世界。本文將對AI技術進行深入探討,從…

開源貢獻 | 基于長安鏈去中心化數字身份合約標準協議(CMDID-1)的DID

DID為每個實體(人、組織、物品等)提供了一個唯一的全球身份標識符,讓用戶可以控制和管理的自己的數字身份,并在使用時以最小化的方式出示,將數據所有權歸還用戶的同時以區塊鏈技術保證了身份的不可篡改性,以…

LeetCode875愛吃香蕉的阿珂

題目描述 珂珂喜歡吃香蕉。這里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警衛已經離開了,將在 h 小時后回來。珂珂可以決定她吃香蕉的速度 k (單位:根/小時)。每個小時,她將會選擇一堆香蕉,從…

IntelliJ IDEA / Android Studio 方法顯示Git提交人

顯示方法: 設置 > 編輯器 > 嵌入提示 > Code Vision > 代碼作者(勾選) IntelliJ IDEA Android Studio

springboot編寫日志環境搭建過程

AOP記錄日志 AOP記錄日志的主要優點包括: 1、低侵入性:AOP記錄日志不需要修改原有的業務邏輯代碼,只需要新增一個切面即可。 2、統一管理:通過AOP記錄日志可以將各個模塊中需要記錄日志的部分進行統一管理,降低了代…

神經網絡的工程基礎(二)——隨機梯度下降法|文末送書

相關說明 這篇文章的大部分內容參考自我的新書《解構大語言模型:從線性回歸到通用人工智能》,歡迎有興趣的讀者多多支持。 本文涉及到的代碼鏈接如下:regression2chatgpt/ch06_optimizer/stochastic_gradient_descent.ipynb 本文將討論利用…

WinApp自動化測試之輔助工具介紹

前篇文章中,我們簡單介紹了部分WinApp自動化測試腳本常規操作,今天我們來講剩余的部分。 文件批量上傳 文件批量上傳和文件單個上傳原理是相同的,單個上傳直接傳入文件路徑即可,批量上傳需要進入批量上傳的文件所在目錄&#xf…

Redis到底是AP還是CP?

這個問題差評,沒問清楚。當然,網上一搜,各種各樣的狗屁答案都有,有時候是AP的,有時候是CP的,薛定諤的Redis。 好的,那應該怎么問呢?Q1.Redis Cluster集群是AP還是CP? A…

uniapp創建支付密碼實現(初始密碼,第二次密碼)

示例: 插件地址:自定義數字/身份證/密碼輸入框,鍵盤密碼框可分離使 - DCloud 插件市場 1.下載插件并導入HBuilderX,找到文件夾,copy number-keyboard.vue一份為number-keyboard2.vue(number-keyboard.vue是…

C++ STL map容器erase操作避坑

map容器的erase方法有三種重載形式: //1.刪除迭代器所指向的元素 //返回值是指向下一個節點的迭代器 iterator erase(iterator it); //2.區間刪除 iterator erase(iterator first, iterator last); //3.根據鍵值刪除 //返回值為刪除的元素個數 size_type erase(con…

民國漫畫雜志《時代漫畫》第37期.PDF

時代漫畫37.PDF: https://url03.ctfile.com/f/1779803-1248636302-c017ee?p9586 (訪問密碼: 9586) 《時代漫畫》的雜志在1934年誕生了,截止1937年6月戰爭來臨被迫停刊共發行了39期。 ps: 資源來源網絡!

C++基礎編程100題-002 OpenJudge-1.1-04 輸出保留3位小數的浮點數

更多資源請關注紐扣編程微信公眾號 002 OpenJudge-1.1-04 輸出保留3位小數的浮點數 http://noi.openjudge.cn/ch0101/04/ 描述 讀入一個單精度浮點數,保留3位小數輸出這個浮點數。 輸入 只有一行,一個單精度浮點數。 輸出 也只有一行,…

塊設備層保序操作分析

Q:塊設備層保序功能的作用? A:通用塊層可以提交一個帶保序標簽(BIO_RW_BARRIER)的BIO到IO請求隊列,塊設備層可以保證在保序BIO之前提交的BIO都先于BIO執行且抵達存儲介質;保序BIO執行完畢后,它需要寫入的數據必定已經抵達存儲介質;在保序IO之后提交的BIO都晚于保序BIO執行,確保…

07.爬蟲---使用session發送請求

07.使用session發送請求 1.目標網站2.代碼實現 1.目標網站 我們以這個網站作為目標網站 http://www.360doc.com/ 注冊用戶 注冊后從登錄界面獲取到這些信息 2.代碼實現 import requestssession requests.Session() url http://www.360doc.com/ajax/login/login.ashx u…