BIO NIO AIO演變
Netty是一個提供異步事件驅動的網絡應用框架,用以快速開發高性能、高可靠的網絡服務器和客戶端程序。Netty簡化了網絡程序的開發,是很多框架和公司都在使用的技術。
Netty並非橫空出世,它是在BIO,NIO,AIO演變中的產物,是一種NIO框架。
一、BIO的理解
網絡編程的基本模型是Client/Server模型,也就是兩個進程之間進行相互通信,其中服務端提供位置信息(綁定的IP地址和監聽端口),客戶端通過連接操作向服務端監聽的
地址發送連接請求,通過三次握手建立連接,如果連接成功,雙方就可以通過網絡套接字(Socket)進行通信。在基於同步堵塞模式開發中,ServerSocket負責綁定Ip地址,啟動監
聽端口。Socket負責發起連接操作。連接成功之后,雙方通過輸入和輸出流進行同步堵塞式通信。
BIO流程圖
BIO 全稱Block-IO 是一種阻塞同步的通信模式。我們常說的StockIO一般指的是BIO。是一個比較傳統的通信方式,模式簡單,使用方便。但並發處理能力低,通信耗時,依賴網速。
BIO 設計原理:
服務器通過一個Acceptor線程負責監聽客戶端請求和為每個客戶端創建一個新的線程進行鏈路處理。典型的一請求一應答模式。若客戶端數量增多,頻繁地創建和銷毀線程會
給服務器打開很大的壓力。后改良為用線程池的方式代替新增線程,被稱為偽異步IO。服務器提供IP地址和監聽的端口,客戶端通過TCP的三次握手與服務器連接,連接成功后,雙
放才能通過套接字(Stock)通信。
小結:BIO模型中通過Socket和ServerSocket完成套接字通道的實現。阻塞,同步,建立連接耗時。
二、NIO的理解
與Socket類和ServerSocket類相對應,NIO也提供了SocketChannel和ServerSocketChannel兩種不同的套接字通道實現。這兩種新增的通道都支持阻塞和非阻塞兩種模
式。阻塞模式使用非常簡單,但是性能和可靠性都不好,非阻塞模式則正好相反。幵發人員一般可以根據自己的需要來選擇合適的模式,一般來說,低負載、低並發的應用程序可
以選擇同步阻塞I/O以降低編程父雜度,但是對於高負載、高並發的網絡絡應用,需要使用NIO的非堵塞模式迸行幵發。
NIO 全稱New IO,也叫Non-Block IO 是一種非阻塞同步的通信模式。
NIO流程圖
NIO 設計原理
NIO 相對於BIO來說一大進步。客戶端和服務器之間通過Channel通信。NIO可以在Channel進行讀寫操作。這些Channel都會被注冊在Selector多路復用器上。Selector通過
一個線程不停的輪詢這些Channel。找出已經准備就緒的Channel執行IO操作。NIO 通過一個線程輪詢,實現千萬個客戶端的請求,這就是非阻塞NIO的特點。
NIO幾個新概念
1)緩沖區Buffer
它是NIO與BIO的一個重要區別。BIO是將數據直接寫入或讀取到Stream對象中。而NIO的數據操作都是在緩沖區中進行的。緩沖區實際上是一個數組。Buffer最常見的類型
是ByteBuffer,另外還有CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer。
2)通道Channel
和流不同,通道是雙向的。NIO可以通過Channel進行數據的讀,寫和同時讀寫操作。通道與流之間不同之處是通道是雙向的,流只能一個方向移動(一個流必須是
InputStream或者OutputStream的子類)。 通道分為兩大類:一類是網絡讀寫(SelectableChannel),一類是用於文件操作(FileChannel),我們使用的SocketChannel
和ServerSocketChannel都是SelectableChannel的子類。
3)多路復用器Selector
NIO編程的基礎。多路復用器提供選擇已經就緒的任務的能力。就是Selector會不斷地輪詢注冊在其上的通道(Channel),如果某個通道處於就緒狀態,會被Selector輪詢出
來,然后通過SelectionKey可以取得就緒的Channel集合,從而進行后續的IO操作。服務器端只要提供一個線程負責Selector的輪詢,就可以接入成千上萬個客戶端,這就是
JDK NIO庫的巨大進步。
三、AIO理解
異步無非是通知系統做一件事情。然后忘掉它,自己做其他事情去了。很多時候系統做完某一件事情后需要一些后續的操作。
AIO 也叫NIO2.0 是一種非阻塞異步的通信模式。在NIO的基礎上引入了新的異步通道的概念,並提供了異步文件通道和異步套接字通道的實現。
AIO流程圖
AIO 並沒有采用NIO的多路復用器,而是使用異步通道的概念。其read,write方法的返回類型都是Future對象。而Future模型是異步的,其核心思想是:去主函數等待時間。
AIO模型中通過AsynchronousSocketChannel和AsynchronousServerSocketChannel完成套接字通道的實現。非阻塞,異步。
四、總結
1 IO,NIO,AIO區別
IO 阻塞同步通信模式,客戶端和服務器連接需要三次握手,使用簡單,但吞吐量小。
NIO 非阻塞同步通信模式,客戶端與服務器通過Channel連接,采用多路復用器輪詢注冊的Channel。提高吞吐量和可靠性。
AIO 非阻塞異步通信模式,NIO的升級版,采用異步通道實現異步通信,其read和write方法均是異步方法。
2 Stock通信的偽代碼實現流程
服務器綁定端口:server = new ServerSocket(PORT)
服務器阻塞監聽:socket = server.accept()
服務器開啟線程:new Thread(Handle handle)
服務器讀寫數據:BufferedReader PrintWriter
客戶端綁定IP和PORT:new Socket(IP_ADDRESS, PORT)
客戶端傳輸接收數據:BufferedReader PrintWriter
3 什么是同步阻塞BIO,同步非阻塞NIO,異步非阻塞AIO
同步阻塞IO : 用戶進程發起一個IO操作以后,必須等待IO操作的真正完成后,才能繼續運行。
同步非阻塞IO: 用戶進程發起一個IO操作以后,可做其它事情,但用戶進程需要經常詢問IO操作是否完成,這樣造成不必要的CPU資源浪費。
異步非阻塞IO: 用戶進程發起一個IO操作然后,立即返回,等IO操作真正的完成以后,應用程序會得到IO操作完成的通知。類比Future模式。
4、小結
1)BIO模型中通過Socket和ServerSocket完成套接字通道實現。阻塞,同步,連接耗時。
2) NIO模型中通過SocketChannel和ServerSocketChannel完成套接字通道實現。非阻塞/阻塞,同步,避免TCP建立連接使用三次握手帶來的開銷。
3) AIO模型中通過AsynchronousSocketChannel和AsynchronousServerSocketChannel完成套接字通道實現。非阻塞,異步。
再附上netty權威指南書中一張圖、
五、參考
主要參考一篇文章:BIO NIO AIO演變 文章中有這三種類型的代碼演示。
GitHub地址: https://github.com/ITDragonBlog/daydayup/tree/master/Netty/socket-io (感謝作者分享)
其它的一些參考:
1、《netty權威指南》第二章
3、Java I/O模型從BIO到NIO和Reactor模式(圖片解釋更清晰)
如果一個人充滿快樂,正面的思想,那么好的人事物就會和他共鳴,而且被他吸引過來。同樣,一個人老帶悲傷,倒霉的事情也會跟過來。
——在自己心情低落的時候,告誡自己不要把負能量帶給別人。(大校9)