title: 【Netty】IO模型
date: 2017-07-17 00:14:18
tags:
- Netty
- Java
categories: Netty
網絡 IO 模型
UNIX 網絡編程對 IO 模型分類, UNIX 提供 5 種 IO 模型
在這 5 個 IO 模型之前,先看看這五個 IO 模型最后的關注點:
用戶 & 內核空間
內核:操作系統(tǒng)的核心茅主,獨立于普通的應用程序昂验,可以訪問受保護的內存空間液样,有訪問底層硬件設備的所有權限
為了保證用戶進程不能直接操作內核(kernel)祟剔,保證內核的安全挚歧,操作系統(tǒng)將虛擬空間劃分為兩部分于宙,一部分為內核空間浮驳,一部分為用戶空間。
緩存 IO
數(shù)據會先拷貝到操作系統(tǒng)內核的緩沖區(qū)捞魁,然后才從操作系統(tǒng)內核的緩沖區(qū)拷貝到應用程序的地址空間
缺點:數(shù)據需要在應用程序空間和內核空間進行數(shù)據拷貝至会,影響效率
有了上面幾個基本概念下面看看網絡 IO
網絡 IO
IO 操作的本質是對數(shù)據的讀寫。因為 IO 緩存的緣故谱俭,一個 IO 操作需要分為兩步奉件,以讀操作為例:
- 等待數(shù)據準備
- 將數(shù)據從內核空間拷貝到用戶空間
對網絡 IO 而言,上面的兩步可以更具象的表述為:
- 等待網絡數(shù)據分組到達昆著,然后將其復制到內核緩沖區(qū)
- 把數(shù)據從內核緩沖區(qū)復制到應用空間緩沖區(qū)
由于網絡傳輸?shù)牟淮_定性县貌,第一步操作可能成為最耗時的過程(可能比后面的業(yè)務邏輯計算都更為耗時)。
下面看 5 個 IO 模型是如何解決問題的凑懂,相關的圖就不放了網上一大把:
阻塞 IO 模型
這個模型下煤痕,其實就是不解決任何問題,第一步接谨,第二部都是阻塞的摆碉。
以 socket 操作為例,進程空間調用 recvfrom脓豪,其系統(tǒng)調用會直到數(shù)據包到達并且復制到應用進程緩沖區(qū)才返回巷帝。
非阻塞 IO 模型
使用輪詢操作,避免第一步操作完全被阻塞扫夜。
進程調用 recvfrom楞泼,如果緩沖區(qū)沒有數(shù)據立即返回一個 EWOULDBLOCK驰徊,通過輪詢操作檢查內核緩沖區(qū)是否有數(shù)據到來。
IO 復用模型
Linux 提供系統(tǒng)調用堕阔,進程將文件描述符傳遞給系統(tǒng)調用辣垒,若第一步未就緒則阻塞在系統(tǒng)調用上。
Linux對 IO 復用模型提供的系統(tǒng)調用:
- select:順序描述所有文件描述符印蔬,文件描述符最多持有 1024 個
- poll:類似于select勋桶,只是去除了文件描述符數(shù)組長度的限制
- epoll:利用mmap技術避免了這些復制和遍歷操作
Java NIO多路復用器 Selector 就是基于 epoll 的多路復用技術實現(xiàn)的
信號驅動 IO 模型
應用進程建立 SIGIO 信號處理程序,調用 sigaction 后返回侥猬。IO 第一步完成后通知程序例驹。
異步 IO
告知內核啟動某個操作,并讓內核在整個操作完成后通知我們退唠。
IO 模型對比
Java 對于 IO 模型的實現(xiàn)
JDK 支持
- JDK 1.0 ~ JDK 1.3:傳統(tǒng)的 BIO鹃锈,基于阻塞 IO 模型
- JDK 1.4 ~ JDK 1.5:加入 NIO辽装,基于 IO 復用模型
- JDK 1.4 ~ JDK 1.5 update10:Selector 基于 select/poll 模型實現(xiàn)
- JDK 1.5 update & Linux core 2.6 以上:Selector 使用 epoll 模型實現(xiàn)
- JDK 1.7 ~ JDK 1.8(目前):加入 NIO 2.0(AIO)耙箍,增加異步套接字通道
使用
參考:
- 《Netty 權威指南》(第2版):第1章腻菇,第2章
- 聊聊并發(fā)苛骨,Part 1:IO模型
- 聊聊Linux 五種IO模型