自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Netty入門:傳統(tǒng)的BIO編程-Netty開發(fā)環(huán)境搭建

開源
在基于傳統(tǒng)同步阻塞模型開發(fā)中,ServerSocket 負(fù)責(zé)綁定 IP 地址,啟動監(jiān)聽端口;Socket 負(fù)責(zé)發(fā)起連接操作。連接成功之后,雙方通過輸入和輸出流進行同步阻塞式通信。

[[285076]]

1.1 傳統(tǒng)的BIO編程

網(wǎng)絡(luò)編程的基本模型是 Client/Server 模型,也就是兩個進程之間進行相互通信,其中服務(wù)端提供位置信息(綁定的 IP 地址和監(jiān)聽端口),客戶端通過連接操作向服務(wù)端監(jiān)聽的地址發(fā)起連接請求,通過三次握手建立連接,如果連接建立成功,雙方就可以通過網(wǎng)絡(luò)套接字(Socket)進行通信。

在基于傳統(tǒng)同步阻塞模型開發(fā)中,ServerSocket 負(fù)責(zé)綁定 IP 地址,啟動監(jiān)聽端口;Socket 負(fù)責(zé)發(fā)起連接操作。連接成功之后,雙方通過輸入和輸出流進行同步阻塞式通信。

1.1.1 BIO 通信模型圖

首先,我們通過圖 2-1 所示的通信模型圖來熟悉下 BIO 的服務(wù)端通信模型:

采用 BIO 通信模型的服務(wù)端,通常由一個獨立的 Acceptor 線程負(fù)責(zé)監(jiān)聽客戶端的連接,它接收到客戶端連接請求之后為每個客戶端創(chuàng)建一個新的線程進行鏈路處理,處理完成之后,通過輸出流返回應(yīng)答給客戶端,線程銷毀。這就是典型的一請求一應(yīng)答通信模型。

 

Netty入門:傳統(tǒng)的BIO編程-Netty開發(fā)環(huán)境搭建

 

圖1-1同步阻塞 1/0服務(wù)端通信模型(1客戶端1線程)

該模型最大的問題就是缺乏彈性伸縮能力,當(dāng)客戶端并發(fā)訪問量增加后,服務(wù)端的線程個數(shù)和客戶端并發(fā)訪問數(shù)呈 1:1 的正比關(guān)系,由于線程是 Java 虛擬機非常寶貴的系統(tǒng)資源,當(dāng)線程數(shù)膨脹之后,系統(tǒng)的性能將急劇下降,隨著并發(fā)訪問量的繼續(xù)增大,系統(tǒng)會發(fā)生線程堆棧溢出、創(chuàng)建新線程失敗等問題,并最終導(dǎo)致進程宕機或者僵死,不能對外提供服務(wù)。

1.2 偽異步I/O編程

為了解決同步阻塞 I/O 面臨的一個鏈路需要一個線程處理的問題,后來有人對它的線程模型進行了優(yōu)化,后端通過一個線程池來處理多個客戶端的請求接入,形成客戶端個數(shù) M:線程池最大線程數(shù) N 的比例關(guān)系,其中 M 可以遠遠大于 N,通過線程池可以靈活的調(diào)配線程資源,設(shè)置線程的最大值,防止由于海量并發(fā)接入導(dǎo)致線程耗盡。

下面,我們結(jié)合連接模型圖和源碼,對偽異步 I/O 進行分析,看它是否能夠解決同步阻塞 I/O 面臨的問題。

1.2.1 偽異步 I/O 模型圖

采用線程池和任務(wù)隊列可以實現(xiàn)一種叫做偽異步的 I/O 通信框架,它的模型圖如圖 1-2 所示。

當(dāng)有新的客戶端接入的時候,將客戶端的 Socket 封裝成一個 Task(該任務(wù)實現(xiàn) java.lang.Runnable 接口)投遞到后端的線程池中進行處理,JDK 的線程池維護一個消息隊列和 N 個活躍線程對消息隊列中的任務(wù)進行處理。由于線程池可以設(shè)置消息隊列的大小和最大線程數(shù),因此,它的資源占用是可控的,無論多少個客戶端并發(fā)訪問,都不會導(dǎo)致資源的耗盡和宕機。

 

Netty入門:傳統(tǒng)的BIO編程-Netty開發(fā)環(huán)境搭建

 

圖 1-2 偽異步I/0服務(wù)端通信模型(M: N)

偽異步 I/O 實際上僅僅只是對之前 I/O 線程模型的一個簡單優(yōu)化,它無法從根本上解決同步 I/O 導(dǎo)致的通信線程阻塞問題。下面我們就簡單分析下如果通信對方返回應(yīng)答時間過長,會引起的級聯(lián)故障。

1. 服務(wù)端處理緩慢,返回應(yīng)答消息耗費60s,平時只需要10ms。

2. 采用偽異步I/O的線程正在讀取故障服務(wù)節(jié)點的響應(yīng),由于讀取輸入流是阻塞的,因此,它將會被同步阻塞60s。

3. 假如所有的可用線程都被故障服務(wù)器阻塞,那后續(xù)所有的I/O消息都將在隊列中排隊。

4. 由于線程池采用阻塞隊列實現(xiàn),當(dāng)隊列積滿之后,后續(xù)入隊列的操作將被阻塞。

5. 由于前端只有一個Accptor線程接收客戶端接入,它被阻塞在線程池的同步阻塞隊列之后,新的客戶端請求消息將被拒絕,客戶端會發(fā)生大量的連接超時。

6. 由于幾乎所有的連接都超時,調(diào)用者會認(rèn)為系統(tǒng)已經(jīng)崩潰,無法接收新的請求消息。

1.3 NIO編程

在介紹 NIO 編程之前,我們首先需要澄清一個概念:NIO 到底是什么的簡稱?

有人稱之為 New I/O,因為它相對于之前的 I/O 類庫是新增的,所以被稱為 NewI/O,這是它的官方叫法。但是,由于之前老的 I/O 類庫是阻塞 I/O,New I/O 類庫的目標(biāo)就是要讓 Java 支持非阻塞 I/O,所以,更多的人喜歡稱之為非阻塞 I/O(Non-block I/O),由于非阻塞 I/O 更能夠體現(xiàn) NIO 的特點,所以本文使用的NIO 都指的是非阻塞 I/O。

與 Socket 類和 ServerSocket 類相對應(yīng),NIO 也提供了 SocketChannel 和ServerSocketChannel 兩種不同的套接字通道實現(xiàn)。這兩種新增的通道都支持阻塞和非阻塞兩種模式。阻塞模式使用非常簡單,但是性能和可靠性都不好,非阻塞模式則正好相反。開發(fā)人員一般可以根據(jù)自己的需要來選擇合適的模式,一般來說,低負(fù)載、低并發(fā)的應(yīng)用程序可以選擇同步阻塞 I/O 以降低編程復(fù)雜度,但是對于高負(fù)載、高并發(fā)的網(wǎng)絡(luò)應(yīng)用,需要使用 NIO 的非阻塞模式進行開發(fā)。

1.4 AIO編程

NIO2.0 引入了新的異步通道的概念,并提供了異步文件通道和異步套接字通道的實現(xiàn)。異步通道提供兩種方式獲取獲取操作結(jié)果:

  • 通過java.util.concurrent.Future類來表示異步操作的結(jié)果;
  • 在執(zhí)行異步操作的時候傳入一個java.nio.channels;
  • CompletionHandler接口的實現(xiàn)類作為操作完成的回調(diào)。

NIO2.0 的異步套接字通道是真正的異步非阻塞 I/O,它對應(yīng) UNIX 網(wǎng)絡(luò)編程中的事件驅(qū)動 I/O(AIO),它不需要通過多路復(fù)用器(Selector)對注冊的通道進行輪詢操作即可實現(xiàn)異步讀寫,從而簡化了 NIO 的編程模型。

1.5 幾種I/O模型對比

不同的 I/O 模型由于線程模型、API 等差別很大,所以用法的差異也非常大。

由于之前的幾個小節(jié)已經(jīng)集中對這幾種 I/O 的 API 和用法進行了說明,本小節(jié)會重點對這幾種 I/O 進行功能對比。如表 2-1 所示。

 

Netty入門:傳統(tǒng)的BIO編程-Netty開發(fā)環(huán)境搭建

 

表 1-1 幾種 I/O 模型的功能和特性對比

1.6 業(yè)界主流的NIO框架介紹

隨著移動互聯(lián)網(wǎng)的發(fā)展和大數(shù)據(jù)時代的到來,大規(guī)模分布式服務(wù)框架、分布式流計算框架已經(jīng)成為架構(gòu)主流,分布式服務(wù)節(jié)點之間的通信形式往往是內(nèi)部長連接,例如 FaceBook 的 Thrift 協(xié)議,為了提升節(jié)點間的通信吞吐量、提升通信性能,目前主流的內(nèi)部通信框架均使用 NIO 框架,對于大公司、技術(shù)積累比較深的團隊可能會使用自研的 NIO 框架來滿足個性化或者行業(yè)特殊的需求,但是大多數(shù)架構(gòu)師會選擇業(yè)界主流的 NIO 框架進行異步通信開發(fā)。

目前,業(yè)界主流的 NIO 框架主要有兩款:Mina 和 Netty,兩者都使用 ApacheLICENSE-2.0 進行開源。不同之處是 Mina 是 Apache 基金會的官方 NIO 框架,Netty 之前是 Jboss 的 NIO 框架,后來脫離 Jboss 獨立申請了 netty.io 域名,與 Jboss 脫離關(guān)系,并對版本進行了重構(gòu),導(dǎo)致 API 無法向上兼容。

Mina 和 Netty 還 有一段 歷 史 淵 源,Mina 最 初 版 本 的 架 構(gòu) 師 是 TrustinLee,后來,由于種種原因,Trustin Lee 離開了 Mina 社區(qū)加入到了 Netty 團隊,重新設(shè)計并開發(fā)了 Netty。很多讀者會發(fā)現(xiàn) Netty 中透著 Mina 的影子,兩個框架的架構(gòu)理念也有很多相似之處,甚至一些代碼都非常相似,原因就在這里。

目前,Mina 和 Netty 的應(yīng)用已經(jīng)非常廣泛,很多開源框架都使用兩者做底層的 NIO 框架,例如 Hadoop 的通信組件 Avro 使用 Netty 做底層的通信框架,

Openfire 則使用 Mina 做底層通信框架,相比于 Mina,Netty 社區(qū)目前更活躍,版本應(yīng)用范圍也更廣。

1.7 為什么選擇Netty

1.7.1 不選擇 Java 原生 NIO 編程的原因

現(xiàn)在我們總結(jié)一下為什么不建議開發(fā)者直接使用 JDK 的 NIO 類庫進行開發(fā),具體原因如下。

1. NIO的類庫和API繁雜,使用麻煩,你需要熟練掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。

2. 需要具備其他的額外技能做鋪墊,例如熟悉Java多線程編程。這是因為NIO編程涉及到Reactor模式,你必須對多線程和網(wǎng)路編程非常熟悉,才能編寫出高質(zhì)量的NIO程序。

3. 可靠性能力補齊,工作量和難度都非常大。例如客戶端面臨斷連重連、網(wǎng)絡(luò)閃斷、半包讀寫、失敗緩存、網(wǎng)絡(luò)擁塞和異常碼流的處理等問題,NIO編程的特點是功能開發(fā)相對容易,但是可靠性能力補齊的工作量和難度都非常大。

4. JDK NIO的BUG,例如臭名昭著的epoll bug,它會導(dǎo)致Selector空輪詢,最終導(dǎo)致CPU 100%。官方聲稱在JDK1.6版本的update18修復(fù)了該問題,但是直到JDK1.7版本該問題仍舊存在,只不過該BUG發(fā)生概率降低了一些而已,它并沒有被根本解決。該BUG以及與該BUG相關(guān)的問題單可以參見以下鏈接內(nèi)容。

  • http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6403933
  • http://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719

由于上述原因,在大多數(shù)場景下,不建議大家直接使用 JDK 的 NIO 類庫,除非你精通 NIO 編程或者有特殊的需求。在絕大多數(shù)的業(yè)務(wù)場景中,我們可以使用NIO 框架 Netty 來進行 NIO 編程,它既可以作為客戶端也可以作為服務(wù)端,同時

支持 UDP 和異步文件傳輸,功能非常強大。

1.7.2 選擇 Netty 的理由

Netty 是業(yè)界最流行的 NIO 框架之一,它的健壯性、功能、性能、可定制性和可擴展性在同類框架中都是首屈一指的,它已經(jīng)得到成百上千的商用項目驗證,例如 Hadoop 的 RPC 框架 avro 使用 Netty 作為底層通信框架;很多其他業(yè)界主流的 RPC 框架,也使用 Netty 來構(gòu)建高性能的異步通信能力。

通過對 Netty 的分析,我們將它的優(yōu)點總結(jié)如下 :

  • API使用簡單,開發(fā)門檻低;
  • 功能強大,預(yù)置了多種編解碼功能,支持多種主流協(xié)議;
  • 定制能力強,可以通過ChannelHandler對通信框架進行靈活地擴展;
  • 性能高,通過與其他業(yè)界主流的NIO框架對比,Netty的綜合性能最優(yōu);
  • 成熟、穩(wěn)定,Netty修復(fù)了已經(jīng)發(fā)現(xiàn)的所有JDK NIO BUG,業(yè)務(wù)開發(fā)人員不需要再為NIO的BUG而煩惱;
  • 社區(qū)活躍,版本迭代周期短,發(fā)現(xiàn)的BUG可以被及時修復(fù),同時,更多的新功能會加入;
  • 經(jīng)歷了大規(guī)模的商業(yè)應(yīng)用考驗,質(zhì)量得到驗證。在互聯(lián)網(wǎng)、大數(shù)據(jù)、網(wǎng)絡(luò)游戲、企業(yè)應(yīng)用、電信軟件等眾多行業(yè)得到成功商用,證明了它已經(jīng)完全能夠滿足不同行業(yè)的商業(yè)應(yīng)用了。

正是因為這些優(yōu)點,Netty 逐漸成為 Java NIO 編程的首選框架。

Netty 的架構(gòu)圖如下所示。

 

Netty入門:傳統(tǒng)的BIO編程-Netty開發(fā)環(huán)境搭建

 

1.8 Netty開發(fā)環(huán)境搭建

首先假設(shè)你已經(jīng)在本機安裝了 JDK1.7,配置了 JDK 的環(huán)境變量 path,同時下載并正確啟動了 IDE 工具 Eclipse。如果你是個 Java 初學(xué)者,從來沒有在本機搭建過 Java 開發(fā)環(huán)境,建議你先選擇一本 Java 基礎(chǔ)入門的書籍或者課程學(xué)習(xí)。

假如你習(xí)慣于使用其他 IDE 工具進行 Java 開發(fā),例如 NetBeans IDE,也可以運行本節(jié)的入門例程。但是,你需要根據(jù)自己實際使用的 IDE 進行對應(yīng)的配置修改和調(diào)整,本書統(tǒng)一使用 eclipse-jee-kepler-SR1-win32 作為 Java 開發(fā)工具。

1.8.1 下載 Netty 類庫

訪問 Netty 的官網(wǎng) http://netty.io/,從【Downloads】標(biāo)簽頁選擇下載4.1.5.Final 軟件包,包含了源碼、編譯類庫和 Java Doc,18.1M 左右,解壓之后的軟件包如下所示。

這時會發(fā)現(xiàn)里面包含了各個模塊的.jar 包和源碼,由于我們直接以二進制類庫的方式使用 Netty,所以只需要獲取 netty-all-4.1.5.Final.jar 即可。

1.8.2 開發(fā)工程搭建

將 netty-all-4.1.5.Final.jar 導(dǎo)入到 Java 工程的 lib 目錄下(lib 目錄需要自建),右鍵單擊 netty

-all-4.1.5.Final.jar,在彈出的菜單中,選擇將.jar包添加到 Build Path 中,即可完成 Netty 開發(fā)環(huán)境的搭建。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2022-04-16 16:52:24

Netty網(wǎng)絡(luò)服務(wù)器客戶端程序

2020-10-10 19:37:27

BIO 、NIO 、A

2020-04-15 08:33:43

Netty網(wǎng)絡(luò)通信

2024-03-26 13:03:16

NettyJavaNIO

2023-12-07 19:48:42

2020-12-25 10:52:28

鴻蒙HarmonyOS應(yīng)用開發(fā)

2011-06-03 16:05:20

IOS 環(huán)境搭建

2011-06-03 15:08:09

IOS 環(huán)境搭建

2011-06-03 15:36:22

IOS 環(huán)境搭建

2011-06-03 14:36:32

IOS 環(huán)境搭建

2023-06-02 08:22:51

Netty網(wǎng)絡(luò)編程

2022-03-04 08:10:35

NettyIO模型Reactor

2020-10-14 08:50:38

搞懂 Netty 線程

2022-12-08 09:10:11

I/O模型Java

2021-07-01 07:51:45

Netty架構(gòu)NIO

2021-06-30 07:19:36

Netty簡單使用

2009-07-03 16:56:37

JSP開發(fā)環(huán)境

2019-07-17 10:10:34

Netty版本Event

2019-04-24 23:49:57

宜人貸蜂巢API網(wǎng)關(guān)Netty

2023-02-28 08:55:33

GatewayNetty服務(wù)
點贊
收藏

51CTO技術(shù)棧公眾號