線程模型簡(jiǎn)介

線程模型簡(jiǎn)介

原聲NIO存在的問(wèn)題

  • NIO的類庫(kù)和API繁雜, 使用麻煩: 需要熟練賬號(hào) Selector嗜憔、ServerSocketChannel桅打、SocketChannel晚缩、ByteBuffer等
  • 需要具備其他的額外技能: 要熟練Java多線程編程溢谤、因?yàn)镹IO編程涉及到Reactor模式, 你必須對(duì)多線程和網(wǎng)絡(luò)編程非常熟悉, 才能編寫出高質(zhì)量的NIO程序.
  • 開發(fā)工作量和難度都非常大 : 例如客戶端面臨斷連重連、網(wǎng)絡(luò)閃斷伶唯、半包讀寫觉既、失敗緩存、網(wǎng)絡(luò)擁塞和異常流的處理等等
  • JDK NIO 的bug : Epoll Bug, 它會(huì)導(dǎo)致Selector空輪詢, 最終導(dǎo)致CPU 100%

原因: 在NIO中通過(guò)Selector的輪詢當(dāng)前是否有IO事件乳幸,根據(jù)JDK NIO api描述瞪讼,Selector的select方法會(huì)一直阻塞,直到IO事件達(dá)到或超時(shí)粹断,但是在Linux平臺(tái)上這里有時(shí)會(huì)出現(xiàn)問(wèn)題符欠,在某些場(chǎng)景下select方法會(huì)直接返回,即使沒(méi)有超時(shí)并且也沒(méi)有IO事件到達(dá)瓶埋,這就是著名的epoll bug希柿,這是一個(gè)比較嚴(yán)重的bug诊沪,它會(huì)導(dǎo)致線程陷入死循環(huán),會(huì)讓CPU飆到100%狡汉,極大地影響系統(tǒng)的可靠性娄徊,到目前為止,JDK都沒(méi)有完全解決這個(gè)問(wèn)題盾戴。

線程模型

  • 傳統(tǒng)阻塞I/O服務(wù)模型

  • Reactor模型

  • 單Reactor 單線程

  • 單Reactor 多線程

  • 主從 Reactor 多線程

傳統(tǒng)阻塞I/O服務(wù)模型

采用阻塞 IO 模式獲取輸入的數(shù)據(jù), 每個(gè)連接都需要獨(dú)立的線程完成數(shù)據(jù)的輸入 , 業(yè)務(wù)處理和數(shù)據(jù)返回工作.

應(yīng)用程序.png
  • 存在問(wèn)題:

  • 當(dāng)并發(fā)數(shù)較大時(shí), 就會(huì)創(chuàng)建大量的線程, 占用很大系統(tǒng)資源

  • 連接創(chuàng)建后, 如果當(dāng)前線程暫時(shí)沒(méi)有數(shù)據(jù)可讀, 該線程會(huì)阻塞在read操作, 造成線程資源浪費(fèi)

Reactor模型

Reactor模式使用IO復(fù)用監(jiān)聽事件, 收到事件后, 分發(fā)給某個(gè)線程(進(jìn)程), 這點(diǎn)就是網(wǎng)絡(luò)服務(wù)器搞并發(fā)處理關(guān)鍵

Reactor模型-Reactor 單線程

  • Selector是可以實(shí)現(xiàn)應(yīng)用程序通過(guò)一個(gè)阻塞對(duì)象監(jiān)聽多路連接請(qǐng)求
  • Reactor對(duì)象通過(guò)Selector監(jiān)控客戶端請(qǐng)求事件, 收到事件后通過(guò)DIspatch進(jìn)行分發(fā)
  • 建立連接請(qǐng)求事件, 則由Acceptor通過(guò)Accept處理連接請(qǐng)求, 然后創(chuàng)建一個(gè)Handler對(duì)象處理連接完成后的后續(xù)業(yè)務(wù)處理
  • Handler會(huì)完成Read->業(yè)務(wù)處理->Send的完整業(yè)務(wù)流程

優(yōu)點(diǎn)

  • 模型簡(jiǎn)單, 沒(méi)有多線程、進(jìn)程通信兵多、競(jìng)爭(zhēng)的問(wèn)題, 全部都在一個(gè)線程中完成

缺點(diǎn)

  • 性能問(wèn)題 : 只有一個(gè)線程, 無(wú)法完全發(fā)揮多核CPU的性能. Handler在處理某個(gè)連接上的業(yè)務(wù)時(shí), 整個(gè)進(jìn)程無(wú)法處理其他連接事件, 很容易導(dǎo)致性能瓶頸
  • 可靠性問(wèn)題 : 線程意外終止或者進(jìn)入死循環(huán), 會(huì)導(dǎo)致整個(gè)系統(tǒng)通信模塊不可用, 不能接受和處理外部消息, 造成節(jié)點(diǎn)故障.
應(yīng)用程序.png

Reactor模型-Reactor 多線程

  • Reactor 對(duì)象通過(guò) selector 監(jiān)控客戶端請(qǐng)求事件, 收到事件后尖啡,通過(guò) dispatch 進(jìn)行分發(fā)
  • 如果建立連接請(qǐng)求, 則右 Acceptor 通過(guò)accept 處理連接請(qǐng)求
  • 如果不是連接請(qǐng)求,則由 reactor 分發(fā)調(diào)用連接對(duì)應(yīng)的 handler 來(lái)處理
  • handler 只負(fù)責(zé)響應(yīng)事件剩膘,不做具體的業(yè)務(wù)處理, 通過(guò) read 讀取數(shù)據(jù)后衅斩,會(huì)分發(fā)給后面的 worker 線程池的某個(gè)線程處理業(yè)務(wù)
  • worker 線程池會(huì)分配獨(dú)立線程完成真正的業(yè)務(wù),并將結(jié)果返回給 handler
  • handler 收到響應(yīng)后怠褐,通過(guò) send 將結(jié)果返回給 client

優(yōu)點(diǎn)

  • 可以充分利用多核CPU的處理能力

缺點(diǎn)

  • 多線程數(shù)據(jù)共享和訪問(wèn)比較復(fù)雜, reactor處理所有的事件的監(jiān)聽和響應(yīng), 在單線程運(yùn)行, 在高并發(fā)場(chǎng)景容易出現(xiàn)性能瓶頸
應(yīng)用程序.png

Reactor模型- 主從Reactor 多線程

  • Reactor 主線程 MainReactor 對(duì)象通過(guò) select 監(jiān)聽客戶端連接事件畏梆,收到事件后,通過(guò) Acceptor 處理客戶端連接事件
  • 當(dāng) Acceptor 處理完客戶端連接事件之后(與客戶端建立好 Socket 連接)奈懒,MainReactor 將 連接分配給 SubReactor奠涌。(即:MainReactor 只負(fù)責(zé)監(jiān)聽客戶端連接請(qǐng)求,和客戶端建立連 接之后將連接交由 SubReactor 監(jiān)聽后面的 IO 事件磷杏。)
  • SubReactor 將連接加入到自己的連接隊(duì)列進(jìn)行監(jiān)聽溜畅,并創(chuàng)建 Handler 對(duì)各種事件進(jìn)行處理 當(dāng)連接上有新事件發(fā)生的時(shí)候,SubReactor 就會(huì)調(diào)用對(duì)應(yīng)的 Handler 處理
  • Handler 通過(guò) read 從連接上讀取請(qǐng)求數(shù)據(jù)极祸,將請(qǐng)求數(shù)據(jù)分發(fā)給 Worker 線程池進(jìn)行業(yè)務(wù)處理 Worker 線程池會(huì)分配獨(dú)立線程來(lái)完成真正的業(yè)務(wù)處理慈格,并將處理結(jié)果返回給 Handler。 Handler 通過(guò) send 向客戶端發(fā)送響應(yīng)數(shù)據(jù)
  • 一個(gè) MainReactor 可以對(duì)應(yīng)多個(gè) SubReactor遥金,即一個(gè) MainReactor 線程可以對(duì)應(yīng)多個(gè) SubReactor 線程

優(yōu)點(diǎn)

  • MainReactor線程與SubReactor線程的數(shù)據(jù)交互簡(jiǎn)單職責(zé)明確, MainReactor線程只需要接受新連接, SubReactor線程完成后續(xù)的業(yè)務(wù)處理
  • MainReactor 線程與SubReactor線程的數(shù)據(jù)交互簡(jiǎn)單, MainReactor線程只需要把新連接傳給SubReactor線程, SubReactor線程無(wú)需返回?cái)?shù)據(jù)
  • 多個(gè)SubReactor線程能夠應(yīng)對(duì)更高的并發(fā)請(qǐng)求

缺點(diǎn)

  • 這種模式的缺點(diǎn)是編程復(fù)雜度較高, 但是由于優(yōu)點(diǎn)明顯, 在許多項(xiàng)目中被廣泛使用, 包括Nginx浴捆、Memcached、Netty等, 這種模式也叫做服務(wù)器的1+M+N線程模式, 即使用該模式開發(fā)的服務(wù)器包含一個(gè)(或多個(gè), 1只是表示相對(duì)較少)連接建立線程+M個(gè)IO線程+N個(gè)業(yè)務(wù)處理線程, 這是業(yè)界成熟的服務(wù)器程序設(shè)計(jì)模式.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末稿械,一起剝皮案震驚了整個(gè)濱河市选泻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溜哮,老刑警劉巖滔金,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茂嗓,居然都是意外死亡餐茵,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門述吸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)忿族,“玉大人锣笨,你說(shuō)我怎么就攤上這事〉琅” “怎么了错英?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)隆豹。 經(jīng)常有香客問(wèn)我椭岩,道長(zhǎng),這世上最難降的妖魔是什么璃赡? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任判哥,我火速辦了婚禮,結(jié)果婚禮上碉考,老公的妹妹穿的比我還像新娘塌计。我一直安慰自己,他們只是感情好侯谁,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布锌仅。 她就那樣靜靜地躺著,像睡著了一般墙贱。 火紅的嫁衣襯著肌膚如雪热芹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天嫩痰,我揣著相機(jī)與錄音剿吻,去河邊找鬼。 笑死串纺,一個(gè)胖子當(dāng)著我的面吹牛丽旅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播纺棺,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼榄笙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了祷蝌?” 一聲冷哼從身側(cè)響起茅撞,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巨朦,沒(méi)想到半個(gè)月后米丘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡糊啡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年拄查,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棚蓄。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堕扶,死狀恐怖碍脏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稍算,我是刑警寧澤典尾,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站糊探,受9級(jí)特大地震影響钾埂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜科平,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一勃教、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匠抗,春花似錦、人聲如沸污抬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)印机。三九已至矢腻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間射赛,已是汗流浹背多柑。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留楣责,地道東北人竣灌。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像秆麸,于是被迫代替她去往敵國(guó)和親初嘹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359