Netty是什么?
作為Java開發(fā)者,相信大家或多或少都聽說過或者是使用過Netty杏死,而說起Netty,就不得不先說一下IO模型捆交。
IO模型
Unix網(wǎng)絡(luò)編程中定義了五種網(wǎng)絡(luò)模型:
- 阻塞IO
- 非阻塞IO
- IO多路復(fù)用
- 信號驅(qū)動IO
- 異步IO
很多朋友在看到IO淑翼、阻塞、非阻塞品追、同步玄括、異步等字眼的時候都感到頭大,之前也和同事討論過這個問題肉瓦。那么是不是阻塞等于同步遭京,非阻塞等于異步?按照我自己的理解來說:
- 同步泞莉、異步:是一種訪問數(shù)據(jù)的方式哪雕,同步需要主動的進(jìn)行數(shù)據(jù)讀寫,而異步則只需要一個數(shù)據(jù)讀寫成功的通知鲫趁,讀寫都由內(nèi)核來完成
- 阻塞斯嚎、非阻塞:是進(jìn)程在IO過程中是否會掛起進(jìn)行等待,如果需要等待則是阻塞挨厚,否則是非阻塞
從上面的描述上可以看到堡僻,凡是異步的IO,就一定是非阻塞的疫剃,不存在異步阻塞IO這種IO模型苦始,前四種IO模型全部是同步IO。一次IO操作簡單來說會經(jīng)歷兩個階段:
- 等待數(shù)據(jù)準(zhǔn)備完成
- 從內(nèi)核將數(shù)據(jù)拷貝至用戶進(jìn)程中
1.阻塞IO
從圖上可以看到慌申,在阻塞IO模型中用戶進(jìn)程發(fā)起一次IO請求陌选,內(nèi)核需要等待數(shù)據(jù)準(zhǔn)備完成理郑,在數(shù)據(jù)準(zhǔn)備完成后,進(jìn)行數(shù)據(jù)拷貝咨油,拷貝完成后給用戶進(jìn)程返回IO成功您炉。從應(yīng)用角度來看,整個IO過程直至內(nèi)核返回成功之前役电,進(jìn)程都處等待操作完成的狀態(tài)赚爵;而從內(nèi)核角度來看,數(shù)據(jù)準(zhǔn)備階段法瑟,需要阻塞等待數(shù)據(jù)準(zhǔn)備完成冀膝,數(shù)據(jù)拷貝階段也需要阻塞等待拷貝完成,IO的兩個階段都被阻塞了霎挟,所以這是一種同步阻塞的IO方式窝剖。
2.非阻塞IO
阻塞IO工作時,用戶進(jìn)程完全被阻塞住而不能進(jìn)行其他的工作酥夭。從圖中可以看出赐纱,當(dāng)用戶進(jìn)程發(fā)出read操作時,如果內(nèi)核中的數(shù)據(jù)還沒有準(zhǔn)備好熬北,那么它并不會阻塞用戶進(jìn)程疙描,而是立刻返回一個error。從用戶進(jìn)程角度講 讶隐,它發(fā)起一個read操作后起胰,并不需要等待,而是馬上就得到了一個結(jié)果巫延。用戶進(jìn)程判斷結(jié)果是一個error時效五,它就知道數(shù)據(jù)還沒有準(zhǔn)備好,于是它可以再次發(fā)送read操作烈评。一旦內(nèi)核中的數(shù)據(jù)準(zhǔn)備好了火俄,并且又再次收到了用戶進(jìn)程的system call犯建,那么它馬上就將數(shù)據(jù)拷貝到了用戶內(nèi)存讲冠,然后返回。在非阻塞式IO中适瓦,用戶進(jìn)程其實是需要不斷的主動詢問內(nèi)核數(shù)據(jù)準(zhǔn)備好了沒有。
3.IO多路復(fù)用
IO多路復(fù)用也會被人們稱為事件驅(qū)動IO。使用select/epoll的好處就在于單個process就可以同時處理多個網(wǎng)絡(luò)連接的IO会涎。它的基本原理就是select/epoll這個方法會不斷的輪詢所負(fù)責(zé)的所有socket宏多,當(dāng)某個socket有數(shù)據(jù)到達(dá)了,就通知用戶進(jìn)程嗦随。用戶進(jìn)程收到通知后進(jìn)行數(shù)據(jù)拷貝的系統(tǒng)調(diào)用列荔,這個階段是從內(nèi)核角度來看阻塞等待數(shù)據(jù)拷貝完成的敬尺,所以IO多路復(fù)用也是一種同步的IO模式。
4.異步IO
用戶進(jìn)程發(fā)起read操作之后贴浙,立刻就可以開始去做其它的事砂吞。而另一方面,從內(nèi)核的角度崎溃,當(dāng)它收到一個異步讀請求之后蜻直,首先會立刻返回,所以不會對用戶進(jìn)程產(chǎn)生任何阻塞袁串。然后概而,內(nèi)核會等待數(shù)據(jù)準(zhǔn)備完成,然后將數(shù)據(jù)拷貝到用戶內(nèi)存囱修,當(dāng)這一切都完成之后赎瑰,內(nèi)核會給用戶進(jìn)程發(fā)送一個signal,告訴它read操作完成了蔚袍。整個過程中都不需要用戶進(jìn)程進(jìn)行主動的阻塞數(shù)據(jù)讀寫操作乡范,完全沒有阻塞。用戶進(jìn)程只需要發(fā)起IO請求啤咽,然后做其他事晋辆,收到IO完成的通知后,直接對數(shù)據(jù)進(jìn)行操作宇整。