BIO、NIO和AIO的區別以及Netty 簡介
要分清這三個,首先要分清這兩組概念。
同步(Synchronization)和異步(Asynchronous)的方式
同步和異步都是基于應用程序所在操作系統處理IO事件所采用的方式,
比如同步:是應用程序要直接參與IO讀寫的操作。
異步:所有的IO讀寫交給搡作系統去處理,應用程序只需要等待通知。
舉個通俗的例子:你打電話問書店老板有沒有《分布式系統》這本書,
如果是同步通信機制,書店老板會說,你稍等,”我查一下",然后開始查啊查,
等查好了(可能是5秒,也可能是一天)告訴你結果(返回結果)。
而異步通信機制,書店老板直接告訴你我查一下啊,查好了打電話給你,然后直接掛電話了(不返回結果)。
然后查好了,他會主動打電話給你。在這里老板通過“回電”這種方式來回調。
阻塞(Block)和非租塞(NonBlock)
阻塞和非阻塞是進程在訪問數據的時候,數據是否準備就緒的一種處理方式,
當數據沒有準備的時候阻塞:往往需要等待緩沖區中的數據準備好過后才處理其他的事情,否則一直等待在那里。
非阻塞:當我們的進程訪問我們的數據緩沖區的時候,如果數據沒有準備好則直接返回不會等待。 如果數據已經準備好,也直接返回。
還是上面的例子,你打電話問書店老板有沒有《分布式系統》這本書,
你如果是阻塞式調用,你會一直把自己“掛起”,直到得到這本書有沒有的結果,
如果是非阻塞式調用,你不管老板有沒有告訴你,你自己先一邊去玩了,
當然你也要偶爾過幾分鐘check一下老板有沒有返回結果。
在這里阻塞與非阻塞與是否同步異步無關。跟老板通過什么方式回答你結果無關。
BIO、NIO和AIO的區別
- BIO:一個連接一個線程,客戶端有連接請求時服務器端就需要啟動一個線程進行處理,線程開銷大。偽異步IO:將請求連接放入線程池,一對多,但線程還是很寶貴的資源。
- NIO:一個請求一個線程,但客戶端發送的連接請求都會注冊到多路復用器上,多路復用器輪詢到連接有I/O請求時才啟動一個線程進行處理。
- AIO:一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啟動線程進行處理。
BIO是面向流的,NIO是面向緩沖區的;BIO的各種流是阻塞的。而NIO是非阻塞的;BIO的Stream是單向的,而NIO的channel是雙向的。
Netty框架
Netty 是基于NIO,對NIO進行封裝的高性能通信框架,很多著名的框架比如Dubbo、Spring5 的新特性Spring WebFlux 等底層都使用到Netty。
Netty的組件
- I/O:各種各樣的流(文件、數組、緩沖、管道。。。)的處理(輸入輸出)。
- Channel:通道,代表一個連接,每個Client請對會對應到具體的一個Channel。
- ChannelPipeline:責任鏈,每個Channel都有且僅有一個ChannelPipeline與之對應,里面是各種各樣的Handler。
- handler:用于處理出入站消息及相應的事件,實現我們自己要的業務邏輯。
- EventLoopGroup:I/O線程池,負責處理Channel對應的I/O事件。
- ServerBootstrap:服務器端啟動輔助對象。
- Bootstrap:客戶端啟動輔助對象。
- ChannelInitializer:Channel初始化器。
- ChannelFuture:代表I/O操作的執行結果,通過事件機制,獲取執行結果,通過添加監聽器,執行我們想要的操作。
- ByteBuf:字節序列,通過ByteBuf操作基礎的字節數組和緩沖區。