Netty中提供了哪些線程模型?
最近,我更新了一些Netty相關(guān)的內(nèi)容,于是有很多粉絲開始私信問我一些關(guān)于Netty的問題。今天,給大家分享一個(gè)大家問得比較多問題,Netty中提供了哪些線程模型?
說(shuō)到線程模型,又不得不說(shuō)Netty中的Reactor,Reactor直譯過來(lái)叫做反應(yīng)堆,它是Netty支持異步多線程的核心組件。常見的Reactor線程模型有三種,分別是:Reactor單線程模型、Reactor多線程模型、主從Reactor多線程模型;
1、單線程單Reactor模型
在Reactor模型有三個(gè)重要的組件:
1、Reactor :主要負(fù)責(zé)將I/O事件發(fā)派給對(duì)應(yīng)的Handler
2、Acceptor :用于處理客戶端連接請(qǐng)求
3、Handlers :執(zhí)行非阻塞的I/O讀寫任務(wù)
首先來(lái)看單線程單Reactor模型,如圖所示:
單線程Reactor這種實(shí)現(xiàn)方式存在缺點(diǎn),因?yàn)?,Handler的執(zhí)行是串行的,如果其中一個(gè)Handler處理線程阻塞,將導(dǎo)致其他的業(yè)務(wù)處理也會(huì)阻塞。而Handler和Reactor在同一個(gè)線程中的執(zhí)行,這也將導(dǎo)致無(wú)法接收新的請(qǐng)求。
2、多線程單Reactor模型
為了解決單線程Reactor的問題,有人提出使用多線程的方式來(lái)處理業(yè)務(wù)邏輯,也就是在業(yè)務(wù)處理的地方加入線程池,實(shí)現(xiàn)異步處理,這樣將Reactor和Handler就放在不同的線程中來(lái)執(zhí)行,這就是多線程單Reactor模型。
但是,問題又來(lái)了,在多線程單Reactor模型中,所有的I/O操作是由一個(gè)Reactor來(lái)完成,而 運(yùn)行在單個(gè)線程中,它需要處理包括accept()/read() /write()/connect()等操作,在并發(fā)量小的情況下影響不大。一旦并發(fā)量上來(lái),出現(xiàn)高負(fù)載、高并發(fā)或大數(shù)據(jù)量的應(yīng)用場(chǎng)景時(shí),容易成為瓶頸,主要有以下2個(gè)原因:
1、一個(gè)NIO線程同時(shí)處理成百上千的鏈路,性能上無(wú)法支撐,即便NIO線程的CPU 達(dá)到100%,也無(wú)法滿足海量消息的讀取和發(fā)送;
2、當(dāng)NIO線程負(fù)載過重之后,處理速度將變慢,這會(huì)導(dǎo)致大量客戶端連接超時(shí),超時(shí)之后往往會(huì)進(jìn)行重發(fā),這更加重了NIO線程的負(fù)載,最終會(huì)導(dǎo)致大量消息積壓和處理超時(shí),成為系統(tǒng)的性能瓶頸;
所以,我們還可以更進(jìn)一步優(yōu)化,引入了主從Reactor多線程模式:
3、主從Reactor多線程模型
如圖所示,在主從Reactor多線程模型中,由三個(gè)主要的角色:
Main Reactor:負(fù)責(zé)接收客戶端的連接請(qǐng)求,并將具體的業(yè)務(wù)IO處理請(qǐng)求轉(zhuǎn)發(fā)給 Sub Reactor(其中Sub Reactor可以有多個(gè))。
Acceptor:請(qǐng)求接收者,它的職責(zé)類似服務(wù)器,并不真正負(fù)責(zé)連接請(qǐng)求的建立,而只將其請(qǐng)求委托 Main Reactor 線程池來(lái)實(shí)現(xiàn),起到一個(gè)轉(zhuǎn)發(fā)的作用。
Sub Reactor:負(fù)責(zé)數(shù)據(jù)的讀寫,在 NIO 中 通常注冊(cè)通道的讀事件(OP_READ)和寫事件(OP_WRITE)。
好了,以上就是我對(duì)Netty線程模型的理解。?