java多线程框架 netty,JavaSocket编程之Netty框架线程模型
1.Netty概述
Netty是一個(gè)由JBoss提供的高效的Java NIO client-server(客戶端-服務(wù)器)開(kāi)發(fā)框架,使用Netty可以快速開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用。Netty提供了一種新的方式來(lái)使開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用程序,使其很容易使用且有很強(qiáng)的可擴(kuò)展性。Netty的內(nèi)部實(shí)現(xiàn)是很復(fù)雜的,但是Netty提供了簡(jiǎn)單易用的API從網(wǎng)絡(luò)處理代碼中解耦業(yè)務(wù)邏輯。Netty是完全基于NIO實(shí)現(xiàn)的,采用事件驅(qū)動(dòng)機(jī)制,非阻塞執(zhí)行,所以整個(gè)Netty都是異步的。Netty框架體系結(jié)構(gòu)圖如下:
Netty框架體系結(jié)構(gòu)圖
2.Java NIO緩沖區(qū)與通道
一個(gè)Buffer對(duì)象是固定數(shù)量的數(shù)據(jù)的容器,其作用是一個(gè)存儲(chǔ)器。通道Channel是I/O傳輸發(fā)生時(shí)通過(guò)的入口,而緩沖區(qū)是這些數(shù)據(jù)傳輸?shù)膩?lái)源或目標(biāo)。對(duì)于離開(kāi)緩沖區(qū)的傳輸,您想傳遞出去的數(shù)據(jù)被置于一個(gè)緩沖區(qū),被傳送到通道。緩沖區(qū)是包在一個(gè)對(duì)象內(nèi)的基本數(shù)據(jù)元素?cái)?shù)組。Buffer類相比一個(gè)簡(jiǎn)單數(shù)組的優(yōu)點(diǎn)是它將關(guān)于數(shù)據(jù)的數(shù)據(jù)內(nèi)容和信息包含在一個(gè)單一的對(duì)象中。緩沖區(qū)家族成員如下所示:
緩沖區(qū)Buffer具有四個(gè)屬性來(lái)提供關(guān)于其所包含的數(shù)據(jù)元素的信息。
它們是:
容量(Capacity):緩沖區(qū)能夠容納的數(shù)據(jù)元素的最大數(shù)量。這一容量在緩沖區(qū)創(chuàng)建時(shí)被設(shè)定,且不能被改變。
上界(Limit):緩沖區(qū)的第一個(gè)不能被讀或?qū)懙脑??;蛘哒f(shuō),緩沖區(qū)中現(xiàn)存元素的計(jì)數(shù)。
位置(Position):下一個(gè)要被讀或?qū)懙脑氐乃饕?。位置?huì)自動(dòng)由相應(yīng)的get( )和put( )函數(shù)更新。
標(biāo)記(Mark):一個(gè)備忘位置。調(diào)用mark( )來(lái)設(shè)定mark = postion。調(diào)用reset( )設(shè)定position = mark。標(biāo)記在設(shè)定前是未定義的(undefined)。
這四個(gè)屬性之間總是遵循以下關(guān)系
0 <= mark <= position <= limit <= capacity
3.Netty核心網(wǎng)絡(luò)模型
Netty是典型的Reactor模型結(jié)構(gòu),在實(shí)現(xiàn)上,Netty中的Boss類充當(dāng)mainReactor,NioWorker類充當(dāng)subReactor(默認(rèn)NioWorker的個(gè)數(shù)是當(dāng)前服務(wù)器的可用核數(shù))。在處理新來(lái)的請(qǐng)求時(shí),NioWorker讀完已收到的數(shù)據(jù)到ChannelBuffer中,之后觸發(fā)ChannelPipeline中的ChannelHandler流。Netty是事件驅(qū)動(dòng),非阻塞的,可以通過(guò)ChannelHandler鏈來(lái)控制執(zhí)行流向。
3.1 Refactor單線程模型
Reactor單線程模型,指的是所有的IO操作都在同一個(gè)NIO線程上面完成;
Reactor單線程模型特點(diǎn):
1)Java NIO服務(wù)端,接收客戶端的TCP連接;
2)Java NIO客戶端,向服務(wù)端發(fā)起TCP連接;
3)Java NIO服務(wù)端/客戶端,讀取通信對(duì)端的請(qǐng)求或者應(yīng)答消息;
4)Java NIO服務(wù)端/客戶端,向通信對(duì)端發(fā)送消息請(qǐng)求或者應(yīng)答消息
使用場(chǎng)景:對(duì)于一些小容量應(yīng)用場(chǎng)景,可以使用單線程模型。但是對(duì)于高負(fù)載、大并發(fā)的應(yīng)用場(chǎng)景卻不合適,比如一個(gè)NIO線程同時(shí)處理成百上千的鏈路,性能上無(wú)法支撐,即便NIO線程的CPU負(fù)荷達(dá)到100%,也無(wú)法滿足海量消息的編碼、解碼、讀取和發(fā)送。Reactor單線程模型如下圖所示:
3.2 Refactor多線程模型
Rector多線程模型與單線程模型最大的區(qū)別就是有一組NIO線程處理IO操作。
Reactor多線程模型的特點(diǎn):
1)有一個(gè)專門的NIO線程-Acceptor線程用于監(jiān)聽(tīng)服務(wù)端,接收客戶端的TCP連接請(qǐng)求;
2)網(wǎng)絡(luò)IO操作-讀、寫(xiě)等由一個(gè)NIO線程池負(fù)責(zé),線程池可以采用標(biāo)準(zhǔn)的JDK線程池實(shí)現(xiàn),它包含一個(gè)任務(wù)隊(duì)列和N個(gè)可用的線程,由這些NIO線程負(fù)責(zé)消息的讀取、解碼、編碼和發(fā)送;
3)1個(gè)NIO線程可以同時(shí)處理N條鏈路,但是1個(gè)鏈路只對(duì)應(yīng)1個(gè)NIO線程,防止發(fā)生并發(fā)操作問(wèn)題。
Reactor多線程模型如下圖所示:
3.3 Netty服務(wù)器端創(chuàng)建過(guò)程
Netty服務(wù)器啟動(dòng)時(shí),創(chuàng)建兩個(gè)NIOEventLoopGroup獨(dú)立的Reator線程池,一個(gè)用于接收客戶端的TCP連接,一個(gè)用于處理IO的相關(guān)的讀寫(xiě)操作。
Netty線程模型是建立在Reactor模型的基礎(chǔ)上,線程模型并不是一成不變的,通過(guò)啟動(dòng)參數(shù)的配置,可以在不同的線程模型之間切換。Netty服務(wù)器端創(chuàng)建過(guò)程序列圖如下:
Netty服務(wù)器端創(chuàng)建過(guò)程序列圖
1)首先創(chuàng)建一個(gè)ServerBootstrap實(shí)例,這是Netty服務(wù)端的啟動(dòng)輔助類;
2)設(shè)置并綁定Reactor線程池,Netty的Reactor線程池是EventLoopGroup,它其實(shí)就是EventLoop線程的數(shù)組。EventLoop的職責(zé)是處理所有注冊(cè)到本線程多路復(fù)用器Selector上的Channel;
3)設(shè)置并綁定服務(wù)端NIOserverSocketChannel, Netty通過(guò)工廠類,利用反射方式創(chuàng)建NioServerSocketChannel對(duì)象
4)設(shè)置TCP連接參數(shù),TCP鏈路建立時(shí)創(chuàng)建并初始化ChannelPipeline,它本質(zhì)是一個(gè)負(fù)責(zé)處理網(wǎng)絡(luò)事件的職責(zé)鏈,負(fù)責(zé)管理和執(zhí)行ChannelHandler。網(wǎng)絡(luò)事件以事件流的形式在ChannelPipeline中流轉(zhuǎn),由ChannelPipeline根據(jù)ChannelHandler的執(zhí)行策略調(diào)度ChannelHandler的執(zhí)行;
5)添加并設(shè)置ChannelHandler,加入到ChannelPipeline事件流;
6)服務(wù)器端綁定監(jiān)聽(tīng)端口,并啟動(dòng)服務(wù)器;
7)啟動(dòng)NioEventLoop負(fù)責(zé)調(diào)度和執(zhí)行Selector輪詢操作,選擇準(zhǔn)備就緒的Channel集合;
8)當(dāng)輪詢到準(zhǔn)備就緒的Channel之后,就由Reactor線程N(yùn)ioEventLoop執(zhí)行ChannelPipeline的相應(yīng)方法;
9)執(zhí)行Netty系統(tǒng)并調(diào)度執(zhí)行ChannelHandler業(yè)務(wù)邏輯
3.4 Netty線程模型實(shí)例
注冊(cè)兩個(gè)OutboundHandler,執(zhí)行順序?yàn)樽?cè)順序的逆序,注冊(cè)兩個(gè)InboundHandler,執(zhí)行順序?yàn)樽?cè)順序,注冊(cè)HelloServerInHandler用于接收客戶端消息已經(jīng)向客戶端發(fā)送消息,主要代碼如下:
本訂閱號(hào)提供Java相關(guān)技術(shù)分享,從Java編程基礎(chǔ)到Java高級(jí)技術(shù),從JavaWeb技術(shù)基礎(chǔ)Jsp、Servlet、>JDBC到SSH、SSM開(kāi)發(fā)框架,從REST風(fēng)格接口設(shè)計(jì)到分布式項(xiàng)目實(shí)戰(zhàn)。剖析主流開(kāi)源技術(shù)框架,用親身
實(shí)踐來(lái)譜寫(xiě)深度Java技術(shù)日志。
Java技術(shù)日志
歡迎關(guān)注 Java技術(shù)日志 微信訂閱號(hào)
總結(jié)
以上是生活随笔為你收集整理的java多线程框架 netty,JavaSocket编程之Netty框架线程模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java8 拼接字符串 StringJo
- 下一篇: 分布式自增ID算法---雪花算法(Sno