Netty框架01_簡介及BIO編程
Netty簡介及BIO編程
一、概述
1. 簡介
1)Netty是由JBOSS提供的一個Java開源框架,現為Github上的獨立項目。
2)Netty是一個異步的、基于事件驅動的網絡應用框架,用以快速開發高性能、高可靠性的網絡IO程序。
注:
1. 基于事件驅動的含義是,Netty會根據客戶端的行為或讀寫來產生相應的事件驅動。
2. 同步指發出請求后等到響應,才可以繼續執行其它行為。
異步指發出請求后不需要等待響應,就可以繼續執行其它行為,比如繼續發請求或者向下執行代碼。
3)Netty主要針對在TCP協議下,面向Clients端的高并發應用,或者Peer-to-Peer場景下的大量數據持續傳輸的應用。
4)Netty本質是一個NIO框架,適用于服務器通訊相關的多種應用場景。
注:
1. 從代碼角度看,Netty的本質是對原生Java的IO的優化和重寫。
2. TCP/IP → 原生JDK(IO/網絡) → NIO(IO/網絡) → Netty框架。各層次之間逐層封裝優化,其中原生JDK(IO/網絡)指Java的IO編程和網絡編程。
2. 應用場景
-
互聯網行業
分布式系統中,各個節點之間需要遠程服務調用,高性能的RPC(遠程過程調用)框架必不可少。Netty作為異步高性能的通信框架,往往作為基礎通信組件被這些RPC框架使用。
典型應用:阿里的分布式服務框架Dubbo的RPC框架使用Dubbo協議進行節點間通信。Dubbo協議默認使用Netty作為基礎通信組件,用于實現各進程節點之間的內部通信。
-
游戲行業
Netty作為高性能的基礎通信組件,提供了TCP/UDP和HTTP協議棧,方便定制和開發私有協議棧,賬號登錄服務器。地圖服務器之間可以方便的通過Netty進行高性能的通信。
-
大數據領域
經典的Hadoop的高性能通信和序列化組件(AVRO 實現數據文件共享)的RPC框架,默認采用Netty進行跨界點通信。它的Netty Service基于Netty框架二次封裝實現。
-
其它開源項目
Akka、Apache Flink、Apache Spark等。
二、I/O模型
I/O模型就是用什么樣的通道進行數據的發送和接收,很大程度上決定了程序通信的性能。
Java共支持3種網絡編輯模型/IO模式:BIO、NIO、AIO。
1. 分類
-
Java BIO (同步并阻塞,傳統阻塞型)
服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,如果線程沒有讀寫到內容,還會造成線程阻塞。
其中,Read/Write表示連接。
-
Java NIO (同步非阻塞)
服務器實現模式為一個線程處理多個請求(連接),即客戶端發送的連接請求都會注冊到多路復用器上,多路復用器輪詢到連接有I/O請求就進行處理。
其中,Server作為Boss,Thread作為Worker Group,Selector也就是多路復用器。而Netty框架基于NIO模型。
-
Java AIO(NIO.2) (異步非阻塞)
AIO引入異步通道的概念,采用了Proactor模式,簡化了程序編寫,有效的請求才啟動線程。它的特點是先由操作系統完成后才通知服務端程序啟動線程去處理,一般適用于連接數較多且連接時間較長的應用。
AIO模型是JDK1.7引入的,但尚未得到廣泛應用。
2. 適用情景
1)BIO方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中。JDK1.4以前的唯一選擇,但程序簡單易理解。
2)NIO方式適用于連接數目多且連接比較短(輕操作)的架構。如聊天服務器,彈幕系統,服務器間通訊等。編程比較復雜,JDK1.4開始支持。
注:Netty框架支持長連接。
3)AIO方式適用于連接數目多且連接比較長(重操作)的架構,如相冊服務器,充分調用OS參與并發操作。編程比較復雜,JDK7開始支持。
三、Java BIO編程
1. 基本介紹
1)Java BIO就是傳統的java io編程,其相關的類和接口在java.io。
2)BIO(blocking I/O):同步阻塞。服務器實現模式為一個連接一個線程,即客戶端有連接請求時,服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,可以通過線程池機制改善(實現多個客戶連接服務器)。
3)BIO方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中。JDK1.4以前的唯一選擇,程序簡單易理解。
2. 工作機制
工作原理圖
見2.1。
BIO編程簡單流程
1)服務器端啟動(或創建)一個ServerSocket。
2)客戶端啟動(或創建)Socket對服務器進行通信。默認情況下服務器端需要對每個客戶建立一個線程與之通訊。
3)客戶端發出請求后,先咨詢服務器是否有線程響應,如果沒有則會等待,或者被拒絕;如果有響應,客戶端線程會等待請求結束后,再繼續執行。
3. 應用實例
步驟
1)使用BIO模型編寫一個服務器端,監聽6666端口,當有客戶端連接時,就啟動一個線程與之通訊。
2)要求使用線程池機制改善,可以連接多個客戶端。
3)服務器端可以接收客戶端發送的數據(客戶端使用dos窗口telnet方式)。
代碼
package com.pfit.bio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BIOServer {
public static void main(String[] args) throws Exception {
//線程池機制
//思路
//1.創建一個線程池
//2.如果有客戶端連接,就創建一個線程,與之通訊(單獨寫一個方法)
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
//創建ServerSocket
ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("服務器啟動了");
while(true) {
//監聽,等待客戶端連接
System.out.println("等待連接");
final Socket socket = serverSocket.accept();
System.out.println("連接到一個客戶端");
//創建一個線程,與之通訊(單獨寫一個方法)
newCachedThreadPool.execute(new Runnable(){
public void run() {//重寫
//可以和客戶端通訊
handler(socket);
}
});
}
}
//編寫一個handler方法,和客戶端通訊
public static void handler(Socket socket) {
try {
System.out.println("線程信息 id = " + Thread.currentThread().getId() + " 名字 = " + Thread.currentThread().getName());
byte[] bytes = new byte[1024];
//通過socket,獲取輸入流
InputStream inputStream = socket.getInputStream();
//循環地讀取客戶端發送的數據
while(true) {
System.out.println("線程信息 id = " + Thread.currentThread().getId() + " 名字 = " + Thread.currentThread().getName());
System.out.println("read……");
int read = inputStream.read(bytes);
if(read != -1) {
//輸出客戶端發送的數據
System.out.println(new String(bytes,0,read));
}else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("關閉和Client的連接");
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
測試
1.客戶端1發送消息,查看日志
2.客戶端2發送消息,查看日志
注:
1. dos窗口進入talent客戶端命令:telnet 127.0.0.1 端口號。
2. telnet客戶端發送指令:先ctrl+],再使用send 指令的方式。
4. 問題分析
1)每個請求都需要創建獨立的線程,與對應的客戶端進行數據Read,業務處理,數據Write。
2)當并發數較大時,需要創建大量線程來處理連接,系統資源占用較大。
3)連接建立后,如果當前線程暫時沒有數據可讀,則線程就阻塞在Read操作上,造成線程資源浪費。
特別鳴謝:@韓順平
參考資料:
注:以上說明均為個人經驗,如有錯誤歡迎指出,筆者虛心改正。如果有更好的方法或者別的問題,也歡迎大家掃文末的微信平臺二維碼,共同交流,共同進步。
智能推薦
高性能Netty學習_01.Java BIO詳解
java BIO編程詳解 一、I/O基本模型 Java BIO 同步并阻塞(傳統阻塞型), 服務器實現模式為一個連接一個線程, 即客戶端有連接請求時服務器端就需要啟動一個線程進行處理, 如果這個連接不做任何事情會造成不必要的線程開銷 . Java NIO : 同步非阻塞, 服務器實現模式為一個線程處理多個請求(連接), 即客戶端發送的連接請求都會注冊到多路復用器上, 多路復用器輪詢到連接有 I/O...
Netty網絡編程框架
一:簡介 Netty是由JBOSS提供的一個java開源框架。Netty提供異步的、事件驅動的網絡應用程序框架和工具,用以快速開發高性能、高可靠性的網絡服務器和客戶端程序。也就是說,Netty 是一個基于NIO的客戶、服務器端編程框架,使用Netty 可以確保你快速和簡單的開發出一個網絡應用,例如實現了某種協議的客戶,服務端應用。Netty相當...
Hibernate框架筆記01_環境搭建_API_CRUD
文章目錄 1. Hibernate框架的概述 1.1 什么是框架 1.2 經典三層架構 1.3 Hibernate框架 2 Hibernate入門 2.1 下載Hibernate的開發包 2.2 創建項目,引入jar包 2.3 創建表 2.4 創建實體類 2.5 創建映射(***) 2.6 創建一個Hibernate的核心配置文件(***) 1.2.7 編寫測試代碼 3 hibernate的常見配...
Django框架 - 01 簡介
Django的簡介: 1. 概述 2. Django中的MVC模式 : 概述 : 一種軟件設計典范, 用一種業務邏輯,數據, 界面顯示分離的方法組織代碼, 將業務邏輯聚集到一個部件里面。 核心思想 : 解耦 圖解 : 編程模式 : 優點 : 降低各功能模塊之間的耦合性, 方便變更, 更容易重構代碼, 最大程度上實現了代碼的重用. 瀏覽器中MVC的表現形式圖解: 3. Django中的MVT模式 :...
Netty學習筆記(一):Netty簡介、三種IO方式、BIO工作機制、BIO應用實例
第 1 章 Netty 背景介紹 一、Netty簡介 Netty 是由 JBOSS 提供的一個 Java 開源框架,現為 Github 上的獨立項目。 Netty 是一個異步的、基于事件驅動的網絡應用框架,用以快速開發高性能、高可靠性的網絡 IO 程序。 Netty 主要針對在 TCP 協議下,面向 Clients 端的高并發應用,或者 Peer-to-Peer 場景下的大量數據持續傳輸的應用。 ...
猜你喜歡
logstash(V1.2+) 01_入門及架構
tmp FPM: https://github.com/jordansissel/fpm The goal of FPM is to be able to easily build platform-native packages. 核心4組件 Shipper: sends events to Logstash –> remote agent… Broker and...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...