netty框架學習記錄
1. 簡介
官方定義為:”Netty 是一款非同步的事件驅動的網路應用程式框架,支援快速地開發可維護的高效能的面向協議的伺服器
和客戶端”,按照慣例貼上一張High Level的架構圖:
縱觀Java系的多種伺服器/大資料框架,都離不開Netty做出的貢獻,本文對Netty做一個簡單的概述
2. 主要特性
Netty有很多重要的特性,主要特性如下:
- 優雅的設計
- 統一的API介面,支援多種傳輸型別,例如OIO,NIO
- 簡單而強大的執行緒模型
- 豐富的文件
- 卓越的效能
- 擁有比原生Java API 更高的效能與更低的延遲
- 基於池化和複用技術,使資源消耗更低
- 安全性
- 完整的SSL/TLS以及StartTLS支援
- 可用於受限環境,如Applet以及OSGI
3. 主要術語
在正式開始之前,先對Netty涉及到的一些術語做個簡單的說明
3.1 IO模型:BIO/NIO/Netty
3.1.1 BIO(Blocking IO):阻塞IO
早期的Java API(java.net)提供了由本地系統套接字型檔提供的所謂的阻塞函式,樣例程式碼如下:
ServerSocket serverSocket = new ServerSocket(portNumber); Socket clientSocket = serverSocket.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter out=new PrintWriter(clientSocket.getOutputStream(), true); String request, response; while ((request = in.readLine()) != null) { if ("Done".equals(request)) { break; } response = processRequest(request); out.println(response); }
這段程式碼片段將只能同時處理一個連線,要管理多個併發客戶端,需要為每個新的客戶端
Socket 建立一個新的 Thread,執行緒模型如下圖所示:
該種模型存在以下兩個問題:
1. 在任何時候都可能有大量的執行緒處於休眠狀態,只是等待輸入或者輸出資料就緒,這可能算是一種資源浪費
2. 需要為每個執行緒的呼叫棧都分配記憶體
3. 即使 Java 虛擬機器(JVM) 在物理上可以支援非常大數量的執行緒, 但是遠在到達該極限之前, 上下文切換所帶來的開銷就會帶來麻煩
3.1.2 NIO(Non Blocking IO):非阻塞IO
Java的NIO特性在JDK 1.4中引入,其結構如下:
從該圖可以看出Selector 是Java 的非阻塞 I/O 實現的關鍵。它使用了事件通知 API
以確定在一組非阻塞套接字中有哪些已經就緒能夠進行 I/O 相關的操作。因為可以在任何的時間檢查任意的讀操作或者寫操作的完成狀態。該種模型下,一個單一的執行緒便可以處理多個併發的連線。
與BIO相比,該模型有以下特點:
1. 使用較少的執行緒便可以處理許多連線,因此也減少了記憶體管理和上下文切換所帶來開銷
2. 當沒有 I/O 操作需要處理的時候,執行緒也可以被用於其他任務
雖然Java 的NIO在效能上比BIO已經相當的優秀,但是要做到如此正確和安全並
不容易。特別是,在高負載下可靠和高效地處理和排程 I/O 操作是一項繁瑣而且容易出錯的任務,此時就時Netty上場的時間了。
3.1.3 Netty
Netty對NIO的API進行了封裝,通過以下手段讓效能又得到了一定程度的提升
1. 使用多路複用技術,提高處理連線的併發性
2. 零拷貝:
1. Netty的接收和傳送資料採用DIRECT BUFFERS,使用堆外直接記憶體進行Socket讀寫,不需要進行位元組緩衝區的二次拷貝
2. Netty提供了組合Buffer物件,可以聚合多個ByteBuffer物件進行一次操作
3. Netty的檔案傳輸採用了transferTo方法,它可以直接將檔案緩衝區的資料傳送到目標Channel,避免了傳統通過迴圈write方式導致的記憶體拷貝問題
3. 記憶體池:為了減少堆外直接記憶體的分配和回收產生的資源損耗問題,Netty提供了基於記憶體池的緩衝區重用機制
4. 使用主從Reactor多執行緒模型,提高併發性
5. 採用了序列無鎖化設計,在IO執行緒內部進行序列操作,避免多執行緒競爭導致的效能下降
6. 預設使用Protobuf的序列化框架
7. 靈活的TCP引數配置
Socket
簡介
套接字是通訊的基石,是支援TCP/IP協議的路通訊的基本操作單元。可以將套接字看作不同主機間的程序進行雙間通訊的端點,它構成了單個主機內及整個網路間的程式設計介面。套接字存在於通訊域中,通訊域是為了處理一般的執行緒通過套接字通訊而引進的一種抽象概念。套接字通常和同一個域中的套接字交換資料(資料交換也可能穿越域的界限,但這時一定要執行某種解釋程式),各種程序使用這個相同的域互相之間用Internet協議簇來進行通訊Socket(套接字)可以看成是兩個網路應用程式進行通訊時,各自通訊連線中的端點,這是一個邏輯上的概念。它是網路環境中程序間通訊的API(應用程式程式設計介面),也是可以被命名和定址的通訊端點,使用中的每一個套接字都有其型別和一個與之相連程序。通訊時其中一個網路應用程式將要傳輸的一段資訊寫入它所在主機的 Socket中,該 Socket通過與網路介面卡(NIC)相連的傳輸介質將這段資訊送到另外一臺主機的 Socket中,使對方能夠接收到這段資訊。 Socket是由IP地址和埠結合的,提供嚮應用層程序傳送資料包的機制