Netty簡述
Netty是一個高性能的網(wǎng)絡編程框架。
上面提到了幾個關鍵的字眼廷粒,高性能窘拯,網(wǎng)絡編程,框架坝茎。這些概括Netty的本質(zhì)涤姊。
Netty是一個NIO客戶端服務器框架,可以快速輕松地開發(fā)協(xié)議服務器和客戶端等網(wǎng)絡應用程序嗤放。它極大地簡化并簡化了TCP和UDP套接字服務器等網(wǎng)絡編程思喊。
“快速簡便”并不意味著最終的應用程序會受到可維護性或性能問題的影響。Netty經(jīng)過精心設計次酌,具有豐富的協(xié)議恨课,如FTP舆乔,SMTP,HTTP以及各種二進制和基于文本的傳統(tǒng)協(xié)議庄呈。因此蜕煌,Netty成功地找到了一種在不妥協(xié)的情況下實現(xiàn)易于開發(fā),性能诬留,穩(wěn)定性和靈活性的方法斜纪。
先來簡單看一下Netty的架構(gòu)圖:
從圖中可以看出,Netty的架構(gòu)分為三塊文兑,核心(Core)盒刚,通信服務(Transport Services)還有各種協(xié)議(Protocol Support)。我們想象將來要學習的內(nèi)容都和這些有關系绿贞。通過架構(gòu)圖對其有個基本印象因块。
Linux? I/O 模型
在Linux中,將I/O模型分為五種類型:
1. 阻塞式?I/O 模型
2. 非阻塞式?I/O 模型
3.?I/O 復用
4. 信號驅(qū)動式?I/O??
5. 異步??I/O?
Linux中的I/O流程概括來說可以分為兩步:
1>等待數(shù)據(jù)準備好(Waiting for the data to be ready)
2>從內(nèi)核向進程復制數(shù)據(jù)(Copying the data from the kernel to the process)
來看下面的圖片:
從上面的流程可以看出籍铁,首先是內(nèi)核空間把數(shù)據(jù)從硬件(磁盤)中讀到內(nèi)核空間的緩沖區(qū)中涡上,進行這一步操作時,數(shù)據(jù)處于內(nèi)核態(tài)拒名,通過磁盤驅(qū)動器吩愧,把數(shù)據(jù)從磁盤讀到內(nèi)核緩沖區(qū)來。下一步是把數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到用戶空間的緩沖區(qū)增显,數(shù)據(jù)由內(nèi)核態(tài)變?yōu)橛脩魬B(tài)雁佳。
知識普及:Linux中的程序大致運行在兩個空間,自己的程序運行在用戶空間同云,用戶空間的權(quán)限有限糖权,相對的另外一個空間是內(nèi)核空間,比如驅(qū)動程序或者一些核心的系統(tǒng)調(diào)用都是在內(nèi)核空間完成的炸站。我們的I/O操作當在一個用戶空間做系統(tǒng)調(diào)用的時候星澳,數(shù)據(jù)會自動從用戶態(tài)變到內(nèi)核態(tài)來進行操作,完成了以后再從內(nèi)核空間拷貝到用戶空間旱易。這種狀態(tài)的切換是為了保證安全禁偎。比如在我們32位的操作系統(tǒng)中,大部分是4G的內(nèi)存咒唆,一般前面一個G主要是內(nèi)核態(tài)使用届垫,后面三個G是用戶態(tài)使用。
阻塞式?I/O 模型
阻塞式I/O是我們最常見的一種IO全释,當我們發(fā)起一個IO請求之后装处,開始進行系統(tǒng)調(diào)用,數(shù)據(jù)變?yōu)閮?nèi)核態(tài),這兩個階段是一直處于阻塞的妄迁。數(shù)據(jù)開始從磁盤拷貝到內(nèi)核空間寝蹈,處理完后再從內(nèi)核空間拷貝到應用空間,數(shù)據(jù)變?yōu)橛脩魬B(tài)登淘。這整個的過程涉及到的所有程序線程都是在等待狀態(tài)箫老。比如我們Java普通的Socket編程,就是這樣一個流程黔州。整個過程中數(shù)據(jù)沒有完成前耍鬓,接收方都是出于等待狀態(tài),這就是阻塞式IO模型流妻。明顯可見效率不會高牲蜀。
非阻塞式?I/O 模型
這種方式的特點是調(diào)用的時候不會等待(也就是不會阻塞),系統(tǒng)如果沒有數(shù)據(jù)绅这,就會立刻告訴你現(xiàn)在沒數(shù)據(jù)涣达,會立刻返回,然后由調(diào)用方自己去問現(xiàn)在有沒有证薇,如果沒有就下次再問有沒有度苔,相當于不斷去輪詢結(jié)果,直到某個時刻被告知有結(jié)果了浑度,這個時候數(shù)據(jù)已經(jīng)從磁盤拷貝到內(nèi)核空間了寇窑,數(shù)據(jù)也處于內(nèi)核態(tài),就差最后從內(nèi)核態(tài)拷貝到用戶空間俺泣,但是疗认,從內(nèi)核空間拷貝到用戶空間完残,讓數(shù)據(jù)從內(nèi)核態(tài)變?yōu)橛脩魬B(tài)伏钠,這個過程在非阻塞式?I/O 模型中,也是阻塞的谨设!所以效率也不會太高熟掂。
I/O 復用模型
復用的意思是,系統(tǒng)一次去查看多個io的進度扎拣,看哪一個有了結(jié)果赴肚,對于有結(jié)果的,就開始執(zhí)行下面從內(nèi)核空間拷貝到用戶空間的操作二蓝,這個模型和上面非阻塞式?I/O 模型的區(qū)別是誉券,非阻塞式?I/O 模型一次只看一個結(jié)果好了沒有,而IO復用模型一次可以查看多個刊愚,一次監(jiān)控一批系統(tǒng)調(diào)用好了沒有踊跟,這是復用模型的特點。在一定程度上鸥诽,能提高一些效率商玫。
信號驅(qū)動式?I/O 模型
在Linux系統(tǒng)中箕憾,有一種信號機制,也就是說調(diào)用方可以注冊一個信號拳昌,當系統(tǒng)調(diào)用完成之后袭异,可以通知這個信號,那注冊信號的人就會知道這個請求已經(jīng)完成了炬藤,這種信號機制應用在IO當中就是信號驅(qū)動式IO御铃。這樣就不是查看結(jié)果是否好了,而是被通知的一種方式沈矿。不過通知后畅买,從內(nèi)核態(tài)到用戶態(tài)這個過程還是阻塞的。純異步的模型就是下面要說的這個细睡。
異步??I/O模型
這種模型是真正的純異步的IO模型谷羞,當開始系統(tǒng)調(diào)用,數(shù)據(jù)從磁盤讀到內(nèi)核空間溜徙,并且從內(nèi)核態(tài)已經(jīng)拷貝到了用戶態(tài)之后湃缎,整個流程已經(jīng)完成了,然后在進行回調(diào)蠢壹,通知調(diào)用方嗓违。主要的區(qū)別在于不是在內(nèi)核空間中完成了就通知,而是由內(nèi)核空間到了用戶空間后再通知图贸,沒有任何阻塞的過程蹂季,是一種更加徹底的異步IO。
各種I/O模型之間的比較
阻塞式IO就是發(fā)起調(diào)用之后疏日,就一直阻塞偿洁,在等著,直到整個IO完成沟优。在這個過程當中涕滋,進程是不能干任何事情的。都在等待挠阁。
非阻塞式IO就是宾肺,進程會主動去問好了沒,好了沒侵俗,好了沒锨用。。隘谣。直到得到回復好了增拥,然后發(fā)起讀請求,把數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間跪者。這個過程是阻塞的棵帽。
IO復用模型渣玲,就是每次都查看多個結(jié)果好了沒逗概,如果發(fā)現(xiàn)n個當中有一兩個有了結(jié)果,就返回忘衍,有結(jié)果的這些開始拷貝逾苫。
信號驅(qū)動式IO模型,就是等數(shù)據(jù)拷貝到內(nèi)核空間再通知枚钓,前面這段時間可以做別的事情铅搓,等內(nèi)核空間準備好了,通知搀捷,再把數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間星掰。
異步IO模型,就是發(fā)起調(diào)用后就徹底不管了嫩舟,等數(shù)據(jù)好了后從內(nèi)核空間拷貝到用戶空間了氢烘,再進行通知,整個過程沒有阻塞的步驟家厌。
從比較重來看播玖,異步IO從理論上來看是最好的,不存在任何阻塞的時間饭于,系統(tǒng)資源理論上可以得到充分利用蜀踏。
同步VS異步
lPOSIX標準將同步I/O和異步I/O定義為:
同步I/O操作:導致請求進程阻塞,直到I/O操作完成掰吕。
異步I/O操作:不導致請求進程阻塞果覆。
從定義上看,只有最后的異步IO模型是真正的異步畴栖,前面四種都達不到真正的異步随静。但是目前來看八千,純異步的IO一直都不太成熟吗讶,比較混亂,沒有一個標準的解決方案恋捆。用的最多的還是IO復用模型照皆,這個是目前為止比較成熟的一個模型。
在Java中沸停,我們用的最多的Socket網(wǎng)絡編程膜毁,就是阻塞式IO模型,后來的NIO就是IO復用模型,在Java中不支持信號驅(qū)動模型瘟滨。Java的NIO2.0候醒,也叫AIO,提供了純異步的IO模型杂瘸,但是現(xiàn)在的異步IO模型還不是很成熟倒淫,所以用的最多的就是NIO册招,也就是IO復用模型沉桌。? ??
推薦書籍《Unix網(wǎng)絡編程》,推薦理由:網(wǎng)絡編程的經(jīng)典之作茂浮,經(jīng)歷了很多年运翼,內(nèi)容基本變化不大返干,原理性書籍,是網(wǎng)絡編程的必看之書血淌。