Netty Reactor 模型之多線程模型
1. 前言
回顧上節(jié),我們了解了什么是傳統(tǒng)堵塞 I/O 模型,什么是單 Reactor 單線程模型,以及它們的缺點(diǎn),本節(jié)內(nèi)容主要是針對(duì)單 Reactor 單線程模型的缺點(diǎn)進(jìn)行升級(jí),讓它的性能得到進(jìn)一步的提高。
2. 如何進(jìn)行優(yōu)化
首先,我們思考一下單 Reactor 單線程的性能瓶頸在哪里?
主要有以下兩個(gè)方面的性能上的缺點(diǎn):
-
整個(gè)流程處理都是單線程,包括:監(jiān)聽客戶端連接、分發(fā)客戶端請(qǐng)求、處理客戶端請(qǐng)求及響應(yīng),整個(gè)流程非常的復(fù)雜和耗時(shí),只有一個(gè)線程的話,如果客戶端數(shù)量比較多,那么將處理不過來(lái);
-
客戶端的監(jiān)聽、請(qǐng)求分發(fā)和業(yè)務(wù)處理耦合一起,業(yè)務(wù)處理將是一個(gè)未知的東西,如果這個(gè)業(yè)務(wù)很復(fù)雜需要連接數(shù)據(jù)庫(kù),并且操作好幾張表,那么可能將會(huì)耗時(shí)相對(duì)的長(zhǎng),那么將會(huì)影響其他的客戶端請(qǐng)求。
針對(duì)單 Reactor 單線程的兩個(gè)缺點(diǎn),本節(jié)我們主要針對(duì)第二個(gè)缺點(diǎn)來(lái)進(jìn)行改造,其實(shí)一般提到線程模型的概念,一般都喜歡結(jié)合生活當(dāng)中的飯店經(jīng)營(yíng)模式這個(gè)俗套來(lái)進(jìn)行說明,可以加深同學(xué)們的印象。
-
單 Reactor 單線程模型: 好比一個(gè)小飯館,老板既要招待客人又要炒菜,老板服務(wù)效率既然很低,掙的錢既然不會(huì)太多;
-
單 Reactor 多線程模型: 老板專門招待客人,并且把客人的點(diǎn)菜傳達(dá)給后廚,后廚有多個(gè)廚師負(fù)責(zé)炒菜,這樣的話,炒菜的速度既然提高,客人也會(huì)覺得滿意;
-
主從多線程模式: 雖然有多個(gè)廚師負(fù)責(zé)炒菜,但是前臺(tái)只要一個(gè)人在忙活,即使后廚炒菜速度很快,那么給客戶上菜的效率也會(huì)受到影響,如果客戶爆滿的話,服務(wù)員只能累死的份了,那怎么辦呢?增加服務(wù)員的人數(shù)不就解決問題了。
3. 單 Reactor 多線程模型
架構(gòu)圖說明:
-
Reactor 通過 Select 監(jiān)聽客戶端請(qǐng)求事件,受到事件之后它本身不負(fù)責(zé)處理,而是把事件轉(zhuǎn)發(fā)出去;
-
如果是建立連接請(qǐng)求,則由 Acceptor 進(jìn)行處理;
-
如果不是建立連接請(qǐng)求,則轉(zhuǎn)發(fā)給 Handler 負(fù)責(zé)處理;
-
Handler 也不負(fù)責(zé)處理具體的業(yè)務(wù),而是通過 read () 方法讀取數(shù)據(jù),然后再次分發(fā)給線程池去進(jìn)行處理;
-
線程池會(huì)分配一個(gè)子線程去處理具體的業(yè)務(wù),處理完成之后把結(jié)果返回給 Handler,并釋放連接給連接池。
模式的優(yōu)點(diǎn):
-
可以充分的利用多核 CPU 的資源,提高處理任務(wù)的性能;
-
把業(yè)務(wù)處理從整個(gè)模型中剝離并丟給線程池去處理,避免某個(gè)業(yè)務(wù)處理或者某次業(yè)務(wù)處理太慢導(dǎo)致其他業(yè)務(wù)處理受到影響;
-
相比傳統(tǒng) I/O 堵塞模型,如果一旦沒有客戶端發(fā)起請(qǐng)求,那么線程池將不會(huì)處于堵塞狀態(tài),而是釋放并且可以處理其他的業(yè)務(wù),對(duì)于性能調(diào)優(yōu)來(lái)說,最寶貴的就是線程資源,一旦線程資源得不到釋放,整個(gè)應(yīng)用將會(huì)卡掉。
模式的缺點(diǎn):
-
多線程之間的數(shù)據(jù)共享和訪問比較復(fù)雜,比如:Handler 給 Worker 線程分發(fā)數(shù)據(jù);
-
Reactor 處理所有事件的監(jiān)聽、轉(zhuǎn)發(fā)、響應(yīng),都是單線程,在高并發(fā)的情況下,負(fù)責(zé)處理業(yè)務(wù)的 Worker 可能正常,但是 Reactor 就會(huì)容易遇到性能瓶頸;
-
Reactor 如果一旦出現(xiàn)故障,那么整個(gè)通訊就會(huì)故障。
通過以上的分析,其實(shí)也是不推薦使用這種模式,除非客戶端數(shù)量比較少,類似局域網(wǎng)內(nèi)部的項(xiàng)目,但是我們還是需要了解整個(gè)模型是如何演變過來(lái)的,而不是一上來(lái)就講解最好的那個(gè)方案。只有把整個(gè)演變過程了解了,我們才能更好的了解整個(gè)線程模型可能存在的性能瓶頸在哪里。
4. 小結(jié)
本節(jié)核心掌握的知識(shí)點(diǎn)
-
了解單 Reactor 單線程的弊端在哪里;
-
通過線程池的方式去解決單 Reactor 單線程存在的缺點(diǎn);
-
通過飯館經(jīng)營(yíng)的案例來(lái)講解幾種 Reactor 線程模型的概念,讓大家更加容易理解;
-
介紹了什么是單 Reactor 多線程模型,以及它的優(yōu)缺點(diǎn)是什么。