wiki:「The reactor design pattern is an event handling pattern for handling service requests delivered concurrently by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to associated request handlers.」
html
對於應用程序而言,CPU 的處理速度是遠遠快於 IO 的速度的。若是CPU爲了IO操做(例如從Socket讀取一段數據)而阻塞顯然是不划算的。好一點的方法是分爲多進程或者線程去進行處理,可是這樣會帶來一些進程切換的開銷,試想一個進程一個數據讀了500ms,期間進程切換到它3次,可是CPU卻什麼都不能幹,就這麼切換走了,是否是也不划算?java
這時先驅們找到了事件驅動,或者叫回調的方式,來完成這件事情。這種方式就是,應用業務向一箇中間人註冊一個回調(event handler),當IO就緒後,就這個中間人產生一個事件,並通知此handler進行處理。這種回調的方式,也體現了「好萊塢原則」(Hollywood principle)-「Don’t call us, we’ll call you」,在咱們熟悉的IoC中也有用到。看來軟件開發真是互通的!react
Reactor 核心是解決多請求問題。通常來講,Thread-Per-Connection 的應用場景併發量不是特別大,若是併發量過大,會致使線程資源瞬間耗盡,致使服務陷入阻塞,這個時候就須要 Reactor 模式來解決這個問題。Reactor 經過多路複用的思想大大減小線程資源的使用。設計模式
上圖是 Reactor 模型,主要涉及的類:多線程
Initiation Dispatcher
:EventHandler 的容器,用來註冊、移除 EventHandler 等;另外,它做爲 Reactor 模式的入口調用 Synchronous Event Demultiplexer 的 select 方法以阻塞等待事件的返回,當阻塞事件返回時,將事件發生的 Handle 分發到相應的 EvenHandler 處理。Even Handler
:定義了事件處理的方法。Handle
:即操做系統中的句柄,是對資源在操做系統層面上的一種抽象,它能夠是打開的文件、一個鏈接(Socket)、Timer等。Synchronous Event Demultiplexer
:使用一個事件循環 ,以阻止全部的資源。當能夠啓動一個同步操做上的資源不會阻塞,多路分解器發送資源到分發器。簡單來講,接收請求和處理請求是同一線程中處理。併發
對於一些小容量應用場景,可使用單線程模型。可是對於高負載、大併發或大數據量的應用場景卻不合適,主要緣由以下: ① 一個NIO線程同時處理成百上千的鏈路,性能上沒法支撐,即使NIO線程的CPU負荷達到100%,也沒法知足海量消息的讀取和發送; ② 當NIO線程負載太重以後,處理速度將變慢,這會致使大量客戶端鏈接超時,超時以後每每會進行重發,這更加劇了NIO線程的負載,最終會致使大量消息積壓和處理超時,成爲系統的性能瓶頸;ide
簡單來講,接收請求和處理請求是不一樣線程中處理。模塊化
mainReactor 通常只有一個,主要負責接收客戶端的鏈接並將其傳遞給 subReactor。subReactor 通常會有多個,主要負責處理與客戶端的通訊。oop
注意:上圖使用了Thread Pool
來處理耗時的業務邏輯,提升Reactor線程的I/O響應,不至於由於一些耗時的業務邏輯而延遲對後面I/O請求的處理。性能
優勢:
缺點:
介紹與 Reactor 相關的 NIO 以及 Netty。