一、背景
對于應用服務器,CPU的處理速度是要遠遠快于IO速度的,如果CPU為了IO操作而阻塞顯然是不劃算的。
處理方式一:分為多進程或者線程去進行處理。缺點:增加一些進程切換的開銷。
處理方式二:事件驅動(或者叫回調的方式),應用業務向一個中間人注冊一個回調(event handler),當IO就緒后,就這個中間人產生一個事件,并通知此handler進行處理。
Reactor為事件驅動中的中間人,它接受所有handler的注冊,并負責檢查操作系統O是否就緒,在就緒后就調用指定handler進行處理。它是一個不斷等待和循環的單獨進程(線程)。
關于NIO中的Reactor模式,請參考Doug Lea的《Scalable IO in Java》。
二、Reactor的幾種模式
在web服務中,很多都涉及基本的操作:read request、decode request、process service、encod reply、send reply等。
1 單線程模式
這是最簡單的單Reactor單線程模型。Reactor線程是個多面手,負責多路分離套接字,Accept新連接,并分派請求到處理器鏈中。該模型適用于處理器鏈中業務處理組件能快速完成的場景。不過這種單線程模型不能充分利用多核資源,所以實際使用的不多。
2 多線程模式(單Reactor)
該模型在事件處理器(Handler)鏈部分采用了多線程(線程池),也是后端程序常用的模型。
3 多線程模式(主從Reactor)
比起第二種模型,它是將Reactor分成兩部分,mainReactor負責監聽并accept新連接,然后將建立的socket通過多路復用器(Acceptor)分派給subReactor。subReactor負責多路分離已連接的socket,讀寫網絡數據;業務處理功能,其交給worker線程池完成。通常,subReactor個數上可與CPU個數等同。(主Reactor用于響應連接請求,從Reactor用于處理IO操作請求!)
好處:因為subReactor也會執行一些比較耗時的IO操作,例如消息的讀寫,使用多個線程去執行,則更加有利于發揮CPU的運算能力,減少IO等待時間。
參考:
http://blog.csdn.net/u013074465/article/details/46276967
http://www.lxweimin.com/p/2461535c38f3
https://github.com/code4craft/netty-learning/blob/master/posts/ch4-reactor.md