俗地講议经,Netty 能做什么斧账?

文章來(lái)源知乎,作者:老錢(qián)

?

作為一個(gè)學(xué)Java的煞肾,如果沒(méi)有研究過(guò)Netty咧织,那么你對(duì)Java語(yǔ)言的使用和理解僅僅停留在表面水平,會(huì)點(diǎn)SSH籍救,寫(xiě)幾個(gè)MVC习绢,訪問(wèn)數(shù)據(jù)庫(kù)和緩存,這些只是初等Java程序員干的事蝙昙。如果你要進(jìn)階闪萄,想了解Java服務(wù)器的深層高階知識(shí),Netty絕對(duì)是一個(gè)必須要過(guò)的門(mén)檻奇颠。

有了Netty败去,你可以實(shí)現(xiàn)自己的HTTP服務(wù)器,F(xiàn)TP服務(wù)器大刊,UDP服務(wù)器为迈,RPC服務(wù)器,WebSocket服務(wù)器缺菌,Redis的Proxy服務(wù)器,MySQL的Proxy服務(wù)器等等搜锰。

如果你想知道Nginx是怎么寫(xiě)出來(lái)的伴郁,如果你想知道Tomcat和Jetty是如何實(shí)現(xiàn)的,如果你也想實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Redis服務(wù)器蛋叼,那都應(yīng)該好好理解一下Netty焊傅,它們高性能的原理都是類(lèi)似的剂陡。

1. 創(chuàng)建一個(gè)ServerSocket,監(jiān)聽(tīng)并綁定一個(gè)端口

2. 一系列客戶(hù)端來(lái)請(qǐng)求這個(gè)端口

3. 服務(wù)器使用Accept狐胎,獲得一個(gè)來(lái)自客戶(hù)端的Socket連接對(duì)象

4. 啟動(dòng)一個(gè)新線(xiàn)程處理連接

4.1 讀Socket鸭栖,得到字節(jié)流

4.2 解碼協(xié)議,得到Http請(qǐng)求對(duì)象

4.3 處理Http請(qǐng)求握巢,得到一個(gè)結(jié)果晕鹊,封裝成一個(gè)HttpResponse對(duì)象

4.4 編碼協(xié)議,將結(jié)果序列化字節(jié)流

4.5 寫(xiě)Socket暴浦,將字節(jié)流發(fā)給客戶(hù)端繼續(xù)

5. 循環(huán)步驟3

HTTP服務(wù)器之所以稱(chēng)為HTTP服務(wù)器溅话,是因?yàn)榫幋a解碼協(xié)議是HTTP協(xié)議,如果協(xié)議是Redis協(xié)議歌焦,那它就成了Redis服務(wù)器飞几,如果協(xié)議是WebSocket,那它就成了WebSocket服務(wù)器独撇,等等屑墨。

使用Netty你就可以定制編解碼協(xié)議,實(shí)現(xiàn)自己的特定協(xié)議的服務(wù)器纷铣。

上面我們說(shuō)的是一個(gè)傳統(tǒng)的多線(xiàn)程服務(wù)器绪钥,這個(gè)也是Apache處理請(qǐng)求的模式。在高并發(fā)環(huán)境下关炼,線(xiàn)程數(shù)量可能會(huì)創(chuàng)建太多程腹,操作系統(tǒng)的任務(wù)調(diào)度壓力大,系統(tǒng)負(fù)載也會(huì)比較高儒拂。那怎么辦呢寸潦?

于是NIO誕生了,NIO并不是Java獨(dú)有的概念社痛,NIO代表的一個(gè)詞匯叫著IO多路復(fù)用见转。它是由操作系統(tǒng)提供的系統(tǒng)調(diào)用,早期這個(gè)操作系統(tǒng)調(diào)用的名字是select蒜哀,但是性能低下斩箫,后來(lái)漸漸演化成了Linux下的epoll和Mac里的kqueue。我們一般就說(shuō)是epoll撵儿,因?yàn)闆](méi)有人拿蘋(píng)果電腦作為服務(wù)器使用對(duì)外提供服務(wù)乘客。而Netty就是基于Java NIO技術(shù)封裝的一套框架。為什么要封裝淀歇,因?yàn)樵腏ava NIO使用起來(lái)沒(méi)那么方便易核,而且還有臭名昭著的bug,Netty把它封裝之后浪默,提供了一個(gè)易于操作的使用模式和接口牡直,用戶(hù)使用起來(lái)也就便捷多了缀匕。

那NIO究竟是什么東西呢?

NIO的全稱(chēng)是NoneBlocking IO碰逸,非阻塞IO乡小,區(qū)別與BIO,BIO的全稱(chēng)是Blocking IO饵史,阻塞IO满钟。那這個(gè)阻塞是什么意思呢?

- Accept是阻塞的约急,只有新連接來(lái)了零远,Accept才會(huì)返回,主線(xiàn)程才能繼

- Read是阻塞的厌蔽,只有請(qǐng)求消息來(lái)了牵辣,Read才能返回,子線(xiàn)程才能繼續(xù)處理

- Write是阻塞的奴饮,只有客戶(hù)端把消息收了纬向,Write才能返回,子線(xiàn)程才能繼續(xù)讀取下一個(gè)請(qǐng)求

所以傳統(tǒng)的多線(xiàn)程服務(wù)器是BlockingIO模式的戴卜,從頭到尾所有的線(xiàn)程都是阻塞的逾条。這些線(xiàn)程就干等在哪里,占用了操作系統(tǒng)的調(diào)度資源投剥,什么事也不干师脂,是浪費(fèi)。

么NIO是怎么做到非阻塞的呢江锨。它用的是事件機(jī)制吃警。它可以用一個(gè)線(xiàn)程把Accept,讀寫(xiě)操作啄育,請(qǐng)求處理的邏輯全干了酌心。如果什么事都沒(méi)得做,它也不會(huì)死循環(huán)挑豌,它會(huì)將線(xiàn)程休眠起來(lái)安券,直到下一個(gè)事件來(lái)了再繼續(xù)干活,這樣的一個(gè)線(xiàn)程稱(chēng)之為NIO線(xiàn)程氓英。

while true {
    events = takeEvents(fds)  // 獲取事件侯勉,如果沒(méi)有事件,線(xiàn)程就休眠
    for event in events {
        if event.isAcceptable {
            doAccept() // 新鏈接來(lái)了
        } elif event.isReadable {
            request = doRead() // 讀消息
            if request.isComplete() {
                doProcess()
            }
        } elif event.isWriteable {
            doWrite()  // 寫(xiě)消息
        }
    }
}
?

NIO的流程大致就是上面的偽代碼描述的過(guò)程债蓝,跟實(shí)際真實(shí)的代碼有較多差異壳鹤,不過(guò)對(duì)于初學(xué)者,這樣理解也是足夠了饰迹。

Netty是建立在NIO基礎(chǔ)之上芳誓,Netty在NIO之上又提供了更高層次的抽象。

在Netty里面啊鸭,Accept連接可以使用單獨(dú)的線(xiàn)程池去處理锹淌,讀寫(xiě)操作又是另外的線(xiàn)程池來(lái)處理。

Accept連接和讀寫(xiě)操作也可以使用同一個(gè)線(xiàn)程池來(lái)進(jìn)行處理赠制。而請(qǐng)求處理邏輯既可以使用單獨(dú)的線(xiàn)程池進(jìn)行處理赂摆,也可以跟放在讀寫(xiě)線(xiàn)程一塊處理。線(xiàn)程池中的每一個(gè)線(xiàn)程都是NIO線(xiàn)程钟些。用戶(hù)可以根據(jù)實(shí)際情況進(jìn)行組裝烟号,構(gòu)造出滿(mǎn)足系統(tǒng)需求的并發(fā)模型。

Netty提供了內(nèi)置的常用編解碼器政恍,包括行編解碼器[一行一個(gè)請(qǐng)求]汪拥,前綴長(zhǎng)度編解碼器[前N個(gè)字節(jié)定義請(qǐng)求的字節(jié)長(zhǎng)度],可重放解碼器[記錄半包消息的狀態(tài)]篙耗,HTTP編解碼器迫筑,WebSocket消息編解碼器等等

Netty提供了一些列生命周期回調(diào)接口,當(dāng)一個(gè)完整的請(qǐng)求到達(dá)時(shí)宗弯,當(dāng)一個(gè)連接關(guān)閉時(shí)脯燃,當(dāng)一個(gè)連接建立時(shí),用戶(hù)都會(huì)收到回調(diào)事件蒙保,然后進(jìn)行邏輯處理辕棚。

Netty可以同時(shí)管理多個(gè)端口,可以使用NIO客戶(hù)端模型邓厕,這些對(duì)于RPC服務(wù)是很有必要的逝嚎。

Netty除了可以處理TCP Socket之外,還可以處理UDP Socket邑狸。在消息讀寫(xiě)過(guò)程中懈糯,需要大量使用ByteBuffer,Netty對(duì)ByteBuffer在性能和使用的便捷性上都進(jìn)行了優(yōu)化和抽象单雾。

總之赚哗,Netty是Java程序員進(jìn)階的必備神奇。如果你知其然硅堆,還想知其所以然屿储,一定要好好研究下Netty。如果你覺(jué)得Java枯燥無(wú)謂渐逃,Netty則是重新開(kāi)啟你對(duì)Java興趣大門(mén)的鑰匙够掠。

讀完一整篇也許你對(duì)Netty還不是特別清晰,可以關(guān)注公眾號(hào)「八戒程序猿」茄菊,發(fā)送「netty教程」即可獲取一套讓你少花時(shí)間疯潭,少走彎路的 netty教程赊堪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市竖哩,隨后出現(xiàn)的幾起案子哭廉,更是在濱河造成了極大的恐慌,老刑警劉巖相叁,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遵绰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡增淹,警方通過(guò)查閱死者的電腦和手機(jī)椿访,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)虑润,“玉大人成玫,你說(shuō)我怎么就攤上這事《巳瑁” “怎么了梁剔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)舞蔽。 經(jīng)常有香客問(wèn)我荣病,道長(zhǎng),這世上最難降的妖魔是什么渗柿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任个盆,我火速辦了婚禮,結(jié)果婚禮上朵栖,老公的妹妹穿的比我還像新娘颊亮。我一直安慰自己,他們只是感情好陨溅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布终惑。 她就那樣靜靜地躺著,像睡著了一般门扇。 火紅的嫁衣襯著肌膚如雪雹有。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天臼寄,我揣著相機(jī)與錄音霸奕,去河邊找鬼。 笑死吉拳,一個(gè)胖子當(dāng)著我的面吹牛质帅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼煤惩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嫉嘀!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起盟庞,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤吃沪,失蹤者是張志新(化名)和其女友劉穎汤善,沒(méi)想到半個(gè)月后什猖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡红淡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年不狮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片在旱。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摇零,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桶蝎,到底是詐尸還是另有隱情驻仅,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布登渣,位于F島的核電站噪服,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胜茧。R本人自食惡果不足惜粘优,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呻顽。 院中可真熱鬧雹顺,春花似錦、人聲如沸廊遍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)喉前。三九已至没酣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間被饿,已是汗流浹背四康。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狭握,地道東北人闪金。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親哎垦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子囱嫩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Netty權(quán)威指南2-讀書(shū)筆記 UNIX網(wǎng)絡(luò)編程5種I/O模型 I/O 復(fù)用模型(最大的優(yōu)勢(shì)是多路復(fù)用)Linux...
    landon30閱讀 514評(píng)論 0 0
  • Netty的簡(jiǎn)單介紹 Netty 是一個(gè) NIO client-server(客戶(hù)端服務(wù)器)框架,使用 Netty...
    AI喬治閱讀 8,402評(píng)論 1 101
  • 1.Netty 是什么漏设? Netty 是 一個(gè)異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架墨闲,用于快速開(kāi)發(fā)可維護(hù)的高性能協(xié)議服務(wù) ...
    Java__JJ閱讀 912評(píng)論 0 2
  • Netty 最流行的 NIO 框架,由 JBOSS 提供的郑口,整合了FTP,SMTP,HTTP協(xié)議 API 簡(jiǎn)單 成...
    mousycoder閱讀 552評(píng)論 0 0
  • 久違的晴天鸳碧,家長(zhǎng)會(huì)。 家長(zhǎng)大會(huì)開(kāi)好到教室時(shí)犬性,離放學(xué)已經(jīng)沒(méi)多少時(shí)間了瞻离。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評(píng)論 16 22