Reactor模型


在Web服務中,處理Web請求時一般有兩種體系,一種是多線程並發模式,服務器端每接收客戶端的一個請求,就開啟一個獨立的線程來服務;還有一種是基於事件驅動,定義一系列事件與其對應的響應函數,並將服務器端接受連接與對事件的處理分離。而Reactor模型和Proactor模型便是事件驅動模型的兩種實現方式,其中Reactor主要應用於同步I/O模式,而Proactor主要用於異步I/O模式。通過使用這樣的模型,能夠提高服務器處理I/O的性能,因此掌握它們的用法很有必要。在閱讀本文之前,可以提前了解操作系統的I/O復用概念與Redis的基礎知識。關於Reactor模型,許多著名的開源項目如Redis都使用了這一模型,接下來就先介紹Reactor是什么,以及在Redis中是如何使用的。
Reactor模型是應對高並發網絡I/O請求的一種技術處理方案,主要用於處理客戶端和服務器端的交互過程。在這一模型中,有三類事件,簡要概括為:

  • 連接事件
  • 讀事件
  • 寫事件

即客戶端與服務器端要建立連接時的連接事件,連接建立后服務器端的讀、寫事件。通過這三個事件,引出了該模型中的三個重要角色:

  • acceptor
  • handler
  • reactor

它們發揮的作用如下:

  • acceptor處理連接事件,在接收連接后,創建handler來處理后續讀寫事件;
  • 在高並發場景下,由於讀、寫事件可能同時發生,因此需要reactor來負責監聽和分配事件。

即有連接請求時,reactor將產生的連接事件交給acceptor處理;有讀、寫請求時,reactor將讀、寫事件交由handler處理,如下圖所示:

在實現上,根據是單線程還是多線程,Reactor模型又分為3類:

  • 單Reactor單線程:accept->read->處理業務邏輯->write都在一個線程中
  • 單Reactor多線程:accept/read/write在一個線程中,業務邏輯處理在另一個線程中
  • 多Reactor多線程/進程:accept在一個線程/進程,read/write/處理業務邏輯在另一個線程/進程

無論是單線程還是多線程/進程,在實現Reactor模型時,都離不開事件驅動框架。事件處理框架是實現Reactor模型時,需要實現的代碼整體控制邏輯,主要包括了兩部分:

  • 事件初始化
  • 事件捕獲、分發、處理的主循環

事件初始化指的是在服務器程序啟動時,創建需要監聽的事件模型,以及該類型對應的handler。而主循環一般使用while循環,在這個循環中,需要捕獲發生的事件,判斷事件類型,並且根據事件類型來調用handler處理事件,如下圖所示:

在Redis中,為了實現事件驅動框架,相應的定義了事件的數據結構、框架的主循環函數、事件捕獲分發函數、事件和handler注冊函數。
主循環函數是aeMain函數,它實現了一個while循環,只要事件停止循環標志不為true,就會一直在這個主循環中。主循環中調用了aeProcessEvents函數,該函數主要用於事件的捕獲與分發,通過查看調用關系能發現,該函數底層是借助操作系統的多路IO復用機制,在Linux下,使用的就是epoll_wait函數來等待事件,並且將准備好的事件返回給aeProcessEvents函數。其調用關系如下圖所示:

在aeProcessEvents函數中,根據事件類型不同,將事件交由不同的處理函數處理。

而在主循環之前,針對每個啟用的IP端口,都使用使用aeCreateFileEvent函數創建對AE_READABLE事件的監聽,並注冊其對應的處理函數.
for (j = 0; j < sfd->count; j++) { if (aeCreateFileEvent(server.el, sfd->fd[j], AE_READABLE, accept_handler,NULL) == AE_ERR) { ... }
而aeCreateFileEvent底層實際上是由epoll_ctl函數實現。

Redis的事件驅動框架主要就是這三個函數,首先注冊事件及其對應處理函數,隨后監聽並捕獲事件,然后使用handler處理事件。
通過使用Reactor模型,Redis能使用單線程處理高並發的I/O請求,從側面反映出Reactor模型的優越性。在個人編程項目中,也推薦使用Reactor模型,從而提升I/O請求處理的效率。

主要參考文章:
https://zhuanlan.zhihu.com/p/95662364
極客時間的《Redis源碼剖析與實戰》課程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM