日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Netty框架整體架構(gòu)及源碼知識(shí)點(diǎn)

 印度阿三17 2019-05-04

Netty概述

Netty是一個(gè)高性能、異步事件驅(qū)動(dòng)的NIO框架,它提供了對(duì)TCP、UDP和文件傳輸?shù)闹С帧W鳛楫?dāng)前最流行的NIO框架,Netty在互聯(lián)網(wǎng)領(lǐng)域、大數(shù)據(jù)分布式計(jì)算領(lǐng)域、游戲行業(yè)、通信行業(yè)等獲得了廣泛的應(yīng)用,一些業(yè)界著名的開源組件也基于Netty的NIO框架構(gòu)建。

Netty 利用 Java 高級(jí)網(wǎng)絡(luò)的能力,隱藏其背后的復(fù)雜性而提供一個(gè)易于使用的 API 構(gòu)建一個(gè)客戶端/服務(wù)端,其具有高并發(fā)、傳輸快、封裝好等特點(diǎn)。

高并發(fā)

Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)開發(fā)的網(wǎng)絡(luò)通信框架,對(duì)比于BIO(Blocking I/O,阻塞IO),他的并發(fā)性能得到了很大提高 。

傳輸快

Netty的傳輸快其實(shí)也是依賴了NIO的一個(gè)特性——零拷貝。

封裝好

Netty封裝了NIO操作的很多細(xì)節(jié),提供易于使用的API,還有心跳、重連機(jī)制、拆包粘包方案等特性,使開發(fā)者能能夠快速高效的構(gòu)建一個(gè)穩(wěn)健的高并發(fā)應(yīng)用。

image

Netty框架

Netty項(xiàng)目致力于提供一個(gè)異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架和工具,用于快速開發(fā)可維護(hù)的、高性能的、高擴(kuò)展性的服務(wù)器和客戶端之間的協(xié)議。換句話說,Netty式一個(gè)NIO客戶端服務(wù)器框架,能夠快速、輕松地開發(fā)網(wǎng)絡(luò)應(yīng)用例如服務(wù)器和客戶端間的協(xié)議。它簡(jiǎn)化了網(wǎng)絡(luò)編程如TCP/IP socket服務(wù)器。

JBOSSes Netty的設(shè)計(jì)吸取了大量的協(xié)議如FTP、SMTP、HTTP和各種二進(jìn)制、基于文本的繼承協(xié)議等協(xié)議的設(shè)計(jì)經(jīng)驗(yàn),成功地找到了一種方法實(shí)現(xiàn)易于開發(fā)、性能、穩(wěn)定、靈活的協(xié)議開發(fā)。

特征:

Netty為用戶提供了很多創(chuàng)新和更好的網(wǎng)絡(luò)開發(fā)體驗(yàn)。

1)設(shè)計(jì)Design

為各種傳輸類型(塊和非塊socket)提供了統(tǒng)一的API;

建立在靈活和可擴(kuò)展的事件模型;

高度可定制的線程模式——單線程,一個(gè)或多個(gè)線程池(如SEDA);

可信的五連接數(shù)據(jù)報(bào)socket支持。

2)易于使用

良好文檔化的Javadoc、用戶向?qū)Ш屠樱?/p>

結(jié)構(gòu)并不臃腫;

無其它的依賴,只需JDK1.5或以上。

3)性能

高吞吐量、低延遲時(shí)間;

很小的資源消耗;

最小化不必要的內(nèi)存復(fù)制。

4)健壯性

不會(huì)因?yàn)榭焖龠B接、慢速連接或超載連接引起OutOfMemoryError錯(cuò)誤;

高速網(wǎng)絡(luò)下不會(huì)引起NIO程序的讀寫異常。

5)安全

完全支持SSL/TLS和StartTLS;

在Java Applet環(huán)境下運(yùn)行正常。

6)社區(qū)

至少每?jī)芍芤粋€(gè)版本發(fā)布。

項(xiàng)目主頁(yè):?http://www./netty/

文檔地址:?http://www./netty/documentation.html

下載地址:?http://www./netty/downloads.html

為什么選擇Netty

Socket通信(IO/NIO/AIO)編程,對(duì)于通信模型已經(jīng)有了一個(gè)基本的認(rèn)識(shí)。我們學(xué)習(xí)的僅僅是一個(gè)模型,如果想把這些真正的用于實(shí)際工作中,那么還需要不斷的完善、擴(kuò)展和優(yōu)化。比如經(jīng)典的TCP讀包寫包問題,或者是數(shù)據(jù)接收的大小,實(shí)際的通信處理與應(yīng)答的處理邏輯等等一些細(xì)節(jié)問題需要認(rèn)真的去思考,而這些都需要大量的時(shí)間和經(jīng)歷,以及豐富的經(jīng)驗(yàn)。所以想學(xué)好Socket通信不是件容易事,那么接下來就來學(xué)習(xí)一下新的技術(shù)Netty,為什么會(huì)選擇Netty?因?yàn)樗?jiǎn)單!使用Netty不必編寫復(fù)雜的邏輯代碼去實(shí)現(xiàn)通信,再也不需要去考慮性能問題,不需要考慮編碼問題,半包讀寫等問題。強(qiáng)大的Netty已經(jīng)幫我們實(shí)現(xiàn)好了,我們只需要使用即可。

Netty是最流行的NIO框架,它的健壯性、功能、性能、可定制性和可擴(kuò)展性在同類框架都是首屈一指的。它已經(jīng)得到成百上千的商業(yè)/商用項(xiàng)目驗(yàn)證,如Hadoop的RPC框架Avro、RocketMQ以及主流的分布式通信框架Dubbox等等。

image

Netty的線程模型

并發(fā)系統(tǒng)可以采用多種并發(fā)編程模型來實(shí)現(xiàn)。并發(fā)模型指定了系統(tǒng)中的線程如何通過協(xié)作來完成分配給它們的作業(yè)。不同的并發(fā)模型采用不同的方式拆分作業(yè),同時(shí)線程間的協(xié)作和交互方式也不相同。

對(duì)于網(wǎng)絡(luò)請(qǐng)求一般可以分為兩個(gè)處理階段,一是接收請(qǐng)求任務(wù),二是處理網(wǎng)絡(luò)請(qǐng)求。根據(jù)不同階段處理方式分為以下幾種線程模型:

串行化處理模型

這個(gè)模型中用一個(gè)線程來處理網(wǎng)絡(luò)請(qǐng)求連接和任務(wù)處理,當(dāng)worker接受到一個(gè)任務(wù)之后,就立刻進(jìn)行處理,也就是說任務(wù)接受和任務(wù)處理是在同一個(gè)worker線程中進(jìn)行的,沒有進(jìn)行區(qū)分。這樣做存在一個(gè)很大的問題是,必須要等待某個(gè)task處理完成之后,才能接受處理下一個(gè)task。

而通常情況下,任務(wù)的處理過程會(huì)比任務(wù)的接受流程慢得多。例如在處理任務(wù)的時(shí)候,我們可能會(huì)需要訪問遠(yuǎn)程數(shù)據(jù)庫(kù),這屬于一種網(wǎng)絡(luò)IO。通常情況下IO操作是比較耗時(shí)的,這直接影響了下一個(gè)任務(wù)的接受,而且通常在IO操作的時(shí)候,CPU是比較空閑的,白白浪費(fèi)了資源。

因此可以把接收任務(wù)和處理任務(wù)兩個(gè)階段分開處理,一個(gè)線程接收任務(wù),放入任務(wù)隊(duì)列,另外的線程異步處理任務(wù)隊(duì)列中的任務(wù)。

并行化處理模型

由于任務(wù)處理一般比較緩慢,會(huì)導(dǎo)致任務(wù)隊(duì)列中任務(wù)積壓長(zhǎng)時(shí)間得不到處理,這時(shí)可以使用多線程來處理。這里使用的是一個(gè)公共的任務(wù)隊(duì)列,多線程環(huán)境中不免要通過加鎖來保證線程安全,我們常用的線程池就是這種模式??梢酝ㄟ^為每個(gè)線程維護(hù)一個(gè)任務(wù)隊(duì)列來改進(jìn)這種模型。

Reactor線程模型

reactor線程模型關(guān)注的是:任務(wù)接受之后,對(duì)處理過程繼續(xù)進(jìn)行切分,劃分為多個(gè)不同的步驟,每個(gè)步驟用不同的線程來處理,也就是原本由一個(gè)線程處理的任務(wù)現(xiàn)在由多個(gè)線程來處理,每個(gè)線程在處理完自己的步驟之后,還需要將任務(wù)轉(zhuǎn)發(fā)到下階段線程繼續(xù)進(jìn)行處理。

Netty的Reactor線程模型

其中mainReacotor,subReactor,Thread Pool是三個(gè)線程池。mainReactor負(fù)責(zé)處理客戶端的連接請(qǐng)求,并將accept的連接注冊(cè)到subReactor的其中一個(gè)線程上;subReactor負(fù)責(zé)處理客戶端通道上的數(shù)據(jù)讀寫;Thread Pool是具體的業(yè)務(wù)邏輯線程池,處理具體業(yè)務(wù)。

Netty具體線程模型

如何理解NioEventLoop和NioEventLoopGroup

1)NioEventLoop實(shí)際上就是工作線程,可以直接理解為一個(gè)線程。NioEventLoopGroup是一個(gè)線程池,線程池中的線程就是NioEventLoop。

2)實(shí)際上bossGroup中有多個(gè)NioEventLoop線程,每個(gè)NioEventLoop綁定一個(gè)端口,也就是說,如果程序只需要監(jiān)聽1個(gè)端口的話,bossGroup里面只需要有一個(gè)NioEventLoop線程就行了。

每個(gè)NioEventLoop都綁定了一個(gè)Selector,所以在Netty的線程模型中,是由多個(gè)Selecotr在監(jiān)聽I(yíng)O就緒事件。而Channel注冊(cè)到Selector。

一個(gè)Channel綁定一個(gè)NioEventLoop,相當(dāng)于一個(gè)連接綁定一個(gè)線程,這個(gè)連接所有的ChannelHandler都是在一個(gè)線程中執(zhí)行的,避免了多線程干擾。更重要的是ChannelPipline鏈表必須嚴(yán)格按照順序執(zhí)行的。單線程的設(shè)計(jì)能夠保證ChannelHandler的順序執(zhí)行。

一個(gè)NioEventLoop的selector可以被多個(gè)Channel注冊(cè),也就是說多個(gè)Channel共享一個(gè)EventLoop。EventLoop的Selecctor對(duì)這些Channel進(jìn)行檢查。

在監(jiān)聽一個(gè)端口的情況下,一個(gè)NioEventLoop通過一個(gè)NioServerSocketChannel監(jiān)聽端口,處理TCP連接。后端多個(gè)工作線程N(yùn)ioEventLoop處理IO事件。每個(gè)Channel綁定一個(gè)NioEventLoop線程,1個(gè)NioEventLoop線程關(guān)聯(lián)一個(gè)selector來為多個(gè)注冊(cè)到它的Channel監(jiān)聽I(yíng)O就緒事件。NioEventLoop是單線程執(zhí)行,保證Channel的pipline在單線程中執(zhí)行,保證了ChannelHandler的執(zhí)行順序。

小編準(zhǔn)備了關(guān)于netty的面試題分享給大家,由于文章篇幅原因以下只分享10道netty的面試題。后五道題未設(shè)置答案,需要獲取答案和更多Java架構(gòu)資料、面試題(含答案)和面試心得以及視頻資料的可以加入Java貓的架構(gòu)學(xué)習(xí)基地:810589193獲?。?/p>

netty面試題

1.BIO、NIO和AIO的區(qū)別?

  • BIO:一個(gè)連接一個(gè)線程,客戶端有連接請(qǐng)求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理。線程開銷大。

  • 偽異步IO:將請(qǐng)求連接放入線程池,一對(duì)多,但線程還是很寶貴的資源。

  • NIO:一個(gè)請(qǐng)求一個(gè)線程,但客戶端發(fā)送的連接請(qǐng)求都會(huì)注冊(cè)到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。

  • AIO:一個(gè)有效請(qǐng)求一個(gè)線程,客戶端的I/O請(qǐng)求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動(dòng)線程進(jìn)行處理,

  • BIO是面向流的,NIO是面向緩沖區(qū)的;BIO的各種流是阻塞的。而NIO是非阻塞的;BIO的Stream是單向的,而NIO的channel是雙向的。

  • NIO的特點(diǎn):事件驅(qū)動(dòng)模型、單線程處理多任務(wù)、非阻塞I/O,I/O讀寫不再阻塞,而是返回0、基于block的傳輸比基于流的傳輸更高效、更高級(jí)的IO函數(shù)zero-copy、IO多路復(fù)用大大提高了Java網(wǎng)絡(luò)應(yīng)用的可伸縮性和實(shí)用性?;赗eactor線程模型。

  • 在Reactor模式中,事件分發(fā)器等待某個(gè)事件或者可應(yīng)用或個(gè)操作的狀態(tài)發(fā)生,事件分發(fā)器就把這個(gè)事件傳給事先注冊(cè)的事件處理函數(shù)或者回調(diào)函數(shù),由后者來做實(shí)際的讀寫操作。如在Reactor中實(shí)現(xiàn)讀:注冊(cè)讀就緒事件和相應(yīng)的事件處理器、事件分發(fā)器等待事件、事件到來,激活分發(fā)器,分發(fā)器調(diào)用事件對(duì)應(yīng)的處理器、事件處理器完成實(shí)際的讀操作,處理讀到的數(shù)據(jù),注冊(cè)新的事件,然后返還控制權(quán)。

2.NIO的組成?

  • Buffer:與Channel進(jìn)行交互,數(shù)據(jù)是從Channel讀入緩沖區(qū),從緩沖區(qū)寫入Channel中的

  • flip方法 : 反轉(zhuǎn)此緩沖區(qū),將position給limit,然后將position置為0,其實(shí)就是切換讀寫模式

  • clear方法 :清除此緩沖區(qū),將position置為0,把capacity的值給limit。

  • rewind方法 : 重繞此緩沖區(qū),將position置為0

  • DirectByteBuffer可減少一次系統(tǒng)空間到用戶空間的拷貝。但Buffer創(chuàng)建和銷毀的成本更高,不可控,通常會(huì)用內(nèi)存池來提高性能。直接緩沖區(qū)主要分配給那些易受基礎(chǔ)系統(tǒng)的本機(jī)I/O 操作影響的大型、持久的緩沖區(qū)。如果數(shù)據(jù)量比較小的中小應(yīng)用情況下,可以考慮使用heapBuffer,由JVM進(jìn)行管理。

  • Channel:表示 IO 源與目標(biāo)打開的連接,是雙向的,但不能直接訪問數(shù)據(jù),只能與Buffer 進(jìn)行交互。通過源碼可知,F(xiàn)ileChannel的read方法和write方法都導(dǎo)致數(shù)據(jù)復(fù)制了兩次!

  • Selector可使一個(gè)單獨(dú)的線程管理多個(gè)Channel,open方法可創(chuàng)建Selector,register方法向多路復(fù)用器器注冊(cè)通道,可以監(jiān)聽的事件類型:讀、寫、連接、accept。注冊(cè)事件后會(huì)產(chǎn)生一個(gè)SelectionKey:它表示SelectableChannel 和Selector 之間的注冊(cè)關(guān)系,wakeup方法:使尚未返回的第一個(gè)選擇操作立即返回,喚醒的原因是:注冊(cè)了新的channel或者事件;channel關(guān)閉,取消注冊(cè);優(yōu)先級(jí)更高的事件觸發(fā)(如定時(shí)器事件),希望及時(shí)處理。

  • Selector在Linux的實(shí)現(xiàn)類是EPollSelectorImpl,委托給EPollArrayWrapper實(shí)現(xiàn),其中三個(gè)native方法是對(duì)epoll的封裝,而EPollSelectorImpl. implRegister方法,通過調(diào)用epoll_ctl向epoll實(shí)例中注冊(cè)事件,還將注冊(cè)的文件描述符(fd)與SelectionKey的對(duì)應(yīng)關(guān)系添加到fdToKey中,這個(gè)map維護(hù)了文件描述符與SelectionKey的映射。

  • fdToKey有時(shí)會(huì)變得非常大,因?yàn)樽?cè)到Selector上的Channel非常多(百萬(wàn)連接);過期或失效的Channel沒有及時(shí)關(guān)閉。fdToKey總是串行讀取的,而讀取是在select方法中進(jìn)行的,該方法是非線程安全的。

  • Pipe:兩個(gè)線程之間的單向數(shù)據(jù)連接,數(shù)據(jù)會(huì)被寫到sink通道,從source通道讀取

  • NIO的服務(wù)端建立過程:Selector.open():打開一個(gè)Selector;ServerSocketChannel.open():創(chuàng)建服務(wù)端的Channel;bind():綁定到某個(gè)端口上。并配置非阻塞模式;register():注冊(cè)Channel和關(guān)注的事件到Selector上;select()輪詢拿到已經(jīng)就緒的事件

3.Netty的特點(diǎn)?

  • 一個(gè)高性能、異步事件驅(qū)動(dòng)的NIO框架,它提供了對(duì)TCP、UDP和文件傳輸?shù)闹С?/p>

  • 使用更高效的socket底層,對(duì)epoll空輪詢引起的cpu占用飆升在內(nèi)部進(jìn)行了處理,避免了直接使用NIO的陷阱,簡(jiǎn)化了NIO的處理方式。

  • 采用多種decoder/encoder 支持,對(duì)TCP粘包/分包進(jìn)行自動(dòng)化處理

  • 可使用接受/處理線程池,提高連接效率,對(duì)重連、心跳檢測(cè)的簡(jiǎn)單支持

  • 可配置IO線程數(shù)、TCP參數(shù), TCP接收和發(fā)送緩沖區(qū)使用直接內(nèi)存代替堆內(nèi)存,通過內(nèi)存池的方式循環(huán)利用ByteBuf

  • 通過引用計(jì)數(shù)器及時(shí)申請(qǐng)釋放不再引用的對(duì)象,降低了GC頻率

  • 使用單線程串行化的方式,高效的Reactor線程模型

  • 大量使用了volitale、使用了CAS和原子類、線程安全類的使用、讀寫鎖的使用

4.Netty的線程模型?

  • Netty通過Reactor模型基于多路復(fù)用器接收并處理用戶請(qǐng)求,內(nèi)部實(shí)現(xiàn)了兩個(gè)線程池,boss線程池和work線程池,其中boss線程池的線程負(fù)責(zé)處理請(qǐng)求的accept事件,當(dāng)接收到accept事件的請(qǐng)求時(shí),把對(duì)應(yīng)的socket封裝到一個(gè)NioSocketChannel中,并交給work線程池,其中work線程池負(fù)責(zé)請(qǐng)求的read和write事件,由對(duì)應(yīng)的Handler處理。

  • 單線程模型:所有I/O操作都由一個(gè)線程完成,即多路復(fù)用、事件分發(fā)和處理都是在一個(gè)Reactor線程上完成的。既要接收客戶端的連接請(qǐng)求,向服務(wù)端發(fā)起連接,又要發(fā)送/讀取請(qǐng)求或應(yīng)答/響應(yīng)消息。一個(gè)NIO 線程同時(shí)處理成百上千的鏈路,性能上無法支撐,速度慢,若線程進(jìn)入死循環(huán),整個(gè)程序不可用,對(duì)于高負(fù)載、大并發(fā)的應(yīng)用場(chǎng)景不合適。

  • 多線程模型:有一個(gè)NIO 線程(Acceptor) 只負(fù)責(zé)監(jiān)聽服務(wù)端,接收客戶端的TCP 連接請(qǐng)求;NIO 線程池負(fù)責(zé)網(wǎng)絡(luò)IO 的操作,即消息的讀取、解碼、編碼和發(fā)送;1 個(gè)NIO 線程可以同時(shí)處理N 條鏈路,但是1 個(gè)鏈路只對(duì)應(yīng)1 個(gè)NIO 線程,這是為了防止發(fā)生并發(fā)操作問題。但在并發(fā)百萬(wàn)客戶端連接或需要安全認(rèn)證時(shí),一個(gè)Acceptor 線程可能會(huì)存在性能不足問題。

  • 主從多線程模型:Acceptor 線程用于綁定監(jiān)聽端口,接收客戶端連接,將SocketChannel 從主線程池的Reactor 線程的多路復(fù)用器上移除,重新注冊(cè)到Sub 線程池的線程上,用于處理I/O 的讀寫等操作,從而保證mainReactor只負(fù)責(zé)接入認(rèn)證、握手等操作;

5.TCP 粘包/拆包的原因及解決方法?

  • TCP是以流的方式來處理數(shù)據(jù),一個(gè)完整的包可能會(huì)被TCP拆分成多個(gè)包進(jìn)行發(fā)送,也可能把小的封裝成一個(gè)大的數(shù)據(jù)包發(fā)送。

  • TCP粘包/分包的原因:

  • 應(yīng)用程序?qū)懭氲淖止?jié)大小大于套接字發(fā)送緩沖區(qū)的大小,會(huì)發(fā)生拆包現(xiàn)象,而應(yīng)用程序?qū)懭霐?shù)據(jù)小于套接字緩沖區(qū)大小,網(wǎng)卡將應(yīng)用多次寫入的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上,這將會(huì)發(fā)生粘包現(xiàn)象;

  • 進(jìn)行MSS大小的TCP分段,當(dāng)TCP報(bào)文長(zhǎng)度-TCP頭部長(zhǎng)度>MSS的時(shí)候?qū)l(fā)生拆包

  • 以太網(wǎng)幀的payload(凈荷)大于MTU(1500字節(jié))進(jìn)行ip分片。

  • 解決方法

  • 消息定長(zhǎng):FixedLengthFrameDecoder類

  • 包尾增加特殊字符分割:行分隔符類:LineBasedFrameDecoder或自定義分隔符類 :DelimiterBasedFrameDecoder

  • 將消息分為消息頭和消息體:LengthFieldBasedFrameDecoder類。分為有頭部的拆包與粘包、長(zhǎng)度字段在前且有頭部的拆包與粘包、多擴(kuò)展頭部的拆包與粘包。

6.了解哪幾種序列化協(xié)議?

7.如何選擇序列化協(xié)議?

8.Netty的零拷貝實(shí)現(xiàn)?

9.Netty的高性能表現(xiàn)在哪些方面?

10.NIOEventLoopGroup源碼?

如果你想突破自己的天花板,那一定要比別人付出更多,這個(gè)過程是很辛苦的。如果你認(rèn)準(zhǔn)了一條路,堅(jiān)持走下去,你一定會(huì)獲得很多收獲和你滿意的答案。

最后,希望以上的分享能給大家?guī)硎斋@。更多面試題領(lǐng)取方式加入Java貓的架構(gòu)學(xué)習(xí)基地:810589193免費(fèi)獲取?。?!


來源:http://www./content-1-180901.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多