Netty专题-(1)初识Netty
寫在前面
最近對Netty這一塊進行了一下學習,因為之前不是很了解。這里在學習的過程中也跟著做了一些筆記,特意整理在這里,希望對想學習的小伙伴有一定的幫助。這里是從最開始的基礎進行學習,所以對于想入門學習Netty的伙伴算是一個不錯的參考,因為筆者自己也差不多是從零基礎開始。當然,學習這些要求已經掌握了 Java 編程等相關的技術棧,比如Java OOP 編程、Java 多線程編程、Java IO 編程 、Java 網 絡編程、常用的 Java 設計模式(比如 觀察者模式 ,命令模式,職責鏈模式 )、常用的數據結構(比如 鏈表)。我會分幾個章節進行整理,希望學習的小伙伴可以堅持學習,如果學不完可以進行收藏,同時也可以關注博主,后期有更新也會第一時間知曉。接下來我們直接開始Netty的學習之旅吧。
1 Netty的介紹
1.1 Netty的基本介紹
(1)Netty 是由 JBOSS 提供的一個 Java 開源框架,現為 Github 上的獨立項目。
(2)Netty 是一個異步的、基于事件驅動的網絡應用框架,用以快速開發高性能、高可靠性的網絡 IO 程序。
(3)Netty 主要針對在 TCP 協議下,面向 Clients 端的高并發應用,或者 Peer-to-Peer 場景下的大量數據持續傳輸的 應用。
(4)Netty 本質是一個 NIO 框架,適用于服務器通訊相關的多種應用場景。
如果想要透徹的理解Netty,需要先學習NIO,這樣以后我們就可以閱讀Netty的源碼,理解其中的原理,當然如果你有能力,也可以去改寫里面的源碼使其滿足你自己的需求。
1.2 Netty的的應用場景
互聯網行業
在分布式系統中,各個節點之間需要遠程服務調用,高性能的 RPC 框架必不可少,Netty 作為 異步高性能的通信框架,往往作為基礎通信組件被這些 RPC 框架使用。阿里分布式服務框架 Dubbo 的 RPC 框架使用 Dubbo 協議進行節點間通信,Dubbo 協議默 認使用 Netty 作為基礎通信組件,用于實現各進程節點之間的內部通信。
游戲行業
無論是手游服務端還是大型的網絡游戲,Java 語言得到了越來越廣泛的應用,Netty 作為高性能的基礎通信組件,提供了 TCP/UDP 和 HTTP 協議棧,方便定制和開發私有協議棧,如賬號登錄服務器,地圖服務器之間可以方便的通過 Netty 進行高性能的通信
大數據領域
經典的 Hadoop 的高性能通信和序列化組件 Avro 的 RPC 框架,默認采用 Netty 進行跨界點通信,它的 Netty Service 基于 Netty 框架二次封裝實現。
2 I/O 模型
上面我們提到,如果想要透徹的理解Netty,需要先學習NIO,NIO屬于IO模型的一種,所以在正式介紹Netty之前我們再談一下I/O模型。
2.1 I/O 模型基本說明
(1)I/O 模型簡單的理解:就是用什么樣的通道進行數據的發送和接收,很大程度上決定了程序通信的性能
(2)Java 共支持 3 種網絡編程模型/IO 模式:BIO、NIO、AIO
(3)Java BIO : 同步并阻塞(傳統阻塞型),服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器 端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷 【如下簡單示意圖】
(4)Java NIO : 同步非阻塞,服務器實現模式為一個線程處理多個請求(連接),即客戶端發送的連接請求都會注 冊到多路復用器上,多路復用器輪詢到連接有 I/O 請求就進行處理 【如下簡單示意圖】
(5)Java AIO(NIO.2) : 異步非阻塞,AIO 引入異步通道的概念,采用了 Proactor 模式,簡化了程序編寫,有效 的請求才啟動線程,它的特點是先由操作系統完成后才通知服務端程序啟動線程去處理,一般適用于連接數較 多且連接時間較長的應用
2.2 BIO、NIO、AIO 適用場景
(1)BIO 方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4 以前的唯一選擇,但程序簡單易理解。
(2)NIO 方式適用于連接數目多且連接比較短(輕操作)的架構,比如聊天服務器,彈幕系統,服務器間通訊等。 編程比較復雜,JDK1.4 開始支持。
(3)AIO 方式使用于連接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用 OS 參與并發操作, 編程比較復雜,JDK7 開始支持。
2.3 Java BIO 介紹
2.3.1 Java BIO 基本介紹
(1)Java BIO 就是傳統的 java io 編程,其相關的類和接口在 java.io
(2)BIO(blocking I/O) : 同步阻塞,服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需 要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,可以通過線程池機制改善(實 現多個客戶連接服務器)。
(3) BIO 方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4 以前的唯一選擇,程序簡單易理解
2.3.2 Java BIO 工作機制
(1)服務器端啟動一個 ServerSocket
(2)客戶端啟動 Socket 對服務器進行通信,默認情況下服務器端需要對每個客戶 建立一個線程與之通訊
(3) 客戶端發出請求后, 先咨詢服務器是否有線程響應,如果沒有則會等待,或者被拒絕
(4)如果有響應,客戶端線程會等待請求結束后,在繼續執行
2.3.3 Java BIO 應用實例
為了讓大家更好的理解,這里寫一個具體的示例供大家理解。我們使用 BIO 模型編寫一個服務器端,監聽 6666 端口,當有客戶端連接時,就啟動一個線程與之通訊,當然我們這里需要使用線程池機制改善,使其可以連接多個客戶端,然后服務器端可以接收客戶端發送的數據。這里使用telnet方式即可,不懂的我后面也會說明。代碼里面會有相關的注釋,大家可以在本地跑著試一下,就可以理解其中的意思,我這里就不做闡述了。
首先是服務端的代碼:
然后我們進行測試,啟動本地的服務端;
然后直接按住home+r,輸入cmd:
來到我們的終端,輸入telnet 127.0.0.1 6666回車:
發現服務端已經連接,等待消息。接下里我們測試發送消息,在進入的終端按住ctrl+],進入發送消息的界面:
然后輸入send + 你想要輸出的內容即可,比如我這里輸入hello,666:
服務端接收成功:
有的伙伴可能輸入telnet以后顯示不是內部命令,別慌,我這里教你怎么去開啟。首先還是按爪home+r,然后輸入control進入控制面板,選擇程序,繼續按照如下步驟。
至此就可以使用telnet命令了。
2.3.2 Java BIO 問題分析
(1)每個請求都需要創建獨立的線程,與對應的客戶端進行數據 Read,業務處理,數據 Write 。
(2)當并發數較大時,需要創建大量線程來處理連接,系統資源占用較大。
(3)連接建立后,如果當前線程暫時沒有數據可讀,則線程就阻塞在 Read 操作上,造成線程資源浪費。
2.4 Java NIO介紹
2.4.1 Java NIO 基本介紹
(1)Java NIO 全稱 java non-blocking IO,是指 JDK 提供的新 API。從 JDK1.4 開始,Java 提供了一系列改進的 輸入/輸出的新特性,被統稱為 NIO(即 New IO),是同步非阻塞的
(2)NIO 相關類都被放在 java.nio 包及子包下,并且對原 java.io 包中的很多類進行改寫。
(3)NIO 有三大核心部分:Channel(通道),Buffer(緩沖區), Selector(選擇器)
(4)NIO 是 面向緩沖區 ,或者面向 塊 編程的。數據讀取到一個它稍后處理的緩沖區,需要時可在緩沖區中前后 移動,這就增加了處理過程中的靈活性,使用它可以提供非阻塞式的高伸縮性網絡
(5)Java NIO 的非阻塞模式,使一個線程從某通道發送請求或者讀取數據,但是它僅能得到目前可用的數據,如果 目前沒有數據可用時,就什么都不會獲取,而不是保持線程阻塞,所以直至數據變的可以讀取之前,該線程可 以繼續做其他的事情。 非阻塞寫也是如此,一個線程請求寫入一些數據到某通道,但不需要等待它完全寫入, 這個線程同時可以去做別的事情。
(6)通俗理解:NIO 是可以做到用一個線程來處理多個操作的。假設有 10000 個請求過來,根據實際情況,可以分配 50 或者 100 個線程來處理。不像之前的阻塞 IO 那樣,非得分配 10000 個。
(7)HTTP2.0 使用了多路復用的技術,做到同一個連接并發處理多個請求,而且并發請求的數量比 HTTP1.1 大了好 幾個數量級
2.4.2 NIO 和 BIO 的比較
(1)BIO 以流的方式處理數據,而 NIO 以塊的方式處理數據,塊 I/O 的效率比流 I/O 高很多
(2)BIO 是阻塞的,NIO 則是非阻塞的
(3)BIO 基于字節流和字符流進行操作,而 NIO 基于 Channel(通道)和 Buffer(緩沖區)進行操作,數據總是從通道 讀取到緩沖區中,或者從緩沖區寫入到通道中。Selector(選擇器)用于監聽多個通道的事件(比如:連接請求, 數據到達等),因此使用單個線程就可以監聽多個客戶端通道
2.4.3 NIO 三大核心原理示意圖
一張圖描述 NIO 的 Selector 、 Channel 和 Buffer 的關系:
(1)每個 channel 都會對應一個 Buffer;
(2)Selector 對應一個線程, 一個線程對應多個 channel(連接);
(3)該圖反應了有三個 channel 注冊到 該 selector //程序 ;
(4) 程序切換到哪個 channel 是有事件決定的, Event 就是一個重要的概念 ;
(5)Selector 會根據不同的事件,在各個通道上切換 ;
(6) Buffer 就是一個內存塊 , 底層是有一個數組 ;
(7)數據的讀取寫入是通過 Buffer, 這個和 BIO , BIO 中要么是輸入流,或者是 輸出流, 不能雙向,但是 NIO 的 Buffer 是可以讀也可以寫, 需要 flip 方法切換 channel 是雙向的, 可以返回底層操作系統的情況, 比如 Linux , 底層的操作系統 通道就是雙向的。
NIO的這三大核心對于后面的Netty講解也很重要,所以對于他們的介紹我會放在下一章,大家可以繼續轉至下一章Netty專題-(2)NIO三大核心閱讀。
猜你感興趣:
Netty專題-(1)初識Netty
Netty專題-(2)NIO三大核心
Netty專題-(3)NIO網絡編程
相關專題持續更新中,敬請期待…
更多文章請點擊:更多…
總結
以上是生活随笔為你收集整理的Netty专题-(1)初识Netty的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MYSQL专题-由简到繁理解索引结构
- 下一篇: Netty专题-(2)NIO三大核心