欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

分布式Netty源碼分析概覽

 更新時(shí)間:2022年03月24日 17:38:20   作者:乒乓狂魔  
這篇文章主要為大家介紹了分布式Netty源碼分析概覽,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

服務(wù)器端demo

看下一個(gè)簡(jiǎn)單的Netty服務(wù)器端的例子

public static void main(String[] args){
	EventLoopGroup bossGroup=new NioEventLoopGroup(1);
	EventLoopGroup workerGroup = new NioEventLoopGroup();
	try {
		ServerBootstrap serverBootstrap=new ServerBootstrap();
		serverBootstrap.group(bossGroup,workerGroup)
			.channel(NioServerSocketChannel.class)
			.option(ChannelOption.SO_BACKLOG, 200)
			.childHandler(new ChannelInitializer<SocketChannel>() {
				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(80,0,4,0,4));
					ch.pipeline().addLast(new StringDecoder(Charset.forName("UTF-8")));
					ch.pipeline().addLast(new TcpServerHandler());
				}
			});
		ChannelFuture f=serverBootstrap.bind(8080).sync();
		f.channel().closeFuture().sync();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}finally {  
        workerGroup.shutdownGracefully();  
        bossGroup.shutdownGracefully();  
    }  
}

先來(lái)簡(jiǎn)單說(shuō)說(shuō)上述遇到的類:

EventLoopGroup介紹

它主要包含2個(gè)方面的功能,注冊(cè)Channel和執(zhí)行一些Runnable任務(wù)。

功能1:先來(lái)看看注冊(cè)Channel

即將Channel注冊(cè)到Selector上,由Selector來(lái)調(diào)度Channel的相關(guān)事件,如讀、寫(xiě)、Accept等事件。

而EventLoopGroup的設(shè)計(jì)是,它包含多個(gè)EventLoop(每一個(gè)EventLoop通常內(nèi)部包含一個(gè)線程),在執(zhí)行上述注冊(cè)過(guò)程中是需要選擇其中的一個(gè)EventLoop來(lái)執(zhí)行上述注冊(cè)行為,這里就出現(xiàn)了一個(gè)選擇策略的問(wèn)題,該選擇策略接口是EventExecutorChooser,你也可以自定義一個(gè)實(shí)現(xiàn)。

從上面可以看到,EventLoopGroup做的工作大部分是一些總體性的工作如初始化上述多個(gè)EventLoop、EventExecutorChooser等,具體的注冊(cè)Channel還是交給它內(nèi)部的EventLoop來(lái)實(shí)現(xiàn)。

功能2:執(zhí)行一些Runnable任務(wù)

EventLoopGroup繼承了EventExecutorGroup,EventExecutorGroup也是EventExecutor的集合,EventExecutorGroup也是掌管著EventExecutor的初始化工作,EventExecutorGroup對(duì)于Runnable任務(wù)的執(zhí)行也是選擇內(nèi)部中的一個(gè)EventExecutor來(lái)做具體的執(zhí)行工作。

netty中很多任務(wù)都是異步執(zhí)行的,一旦當(dāng)前線程要對(duì)某個(gè)EventLoop執(zhí)行相關(guān)操作,如注冊(cè)Channel到某個(gè)EventLoop,如果當(dāng)前線程和所要操作的EventLoop內(nèi)部的線程不是同一個(gè),則當(dāng)前線程就僅僅向EventLoop提交一個(gè)注冊(cè)任務(wù),對(duì)外返回一個(gè)ChannelFuture。

總結(jié):EventLoopGroup含有上述2種功能,它更多的是一個(gè)集合,但是具體的功能實(shí)現(xiàn)還是選擇內(nèi)部的一個(gè)item元素來(lái)執(zhí)行相關(guān)任務(wù)。 這里的內(nèi)部item元素通常即實(shí)現(xiàn)了EventLoop,又實(shí)現(xiàn)了EventExecutor,如NioEventLoop等

ChannelPipeline介紹

上述EventLoopGroup可以將一個(gè)Channel注冊(cè)到內(nèi)部的一個(gè)EventLoop的Selector上,然后對(duì)于這個(gè)Channel的相關(guān)讀寫(xiě)等事件,Netty專門(mén)設(shè)計(jì)了一個(gè)ChannelPipeline來(lái)進(jìn)行處理。每一個(gè)Channel都有一個(gè)ChannelPipeline來(lái)處理該Channel的讀寫(xiě)等事件。

bind過(guò)程

上述serverBootstrap的bind過(guò)程如下:

  • 創(chuàng)建出你所指定的NioServerSocketChannel,然后初始化一些Socket方面的參數(shù)
  • 為上述Channel的ChannelPipeline配置一個(gè)ChannelHandler,該ChannelHandler的作用就是在該Channel成功注冊(cè)到Selector上的時(shí)候,初始化一些邏輯,即initChannel方法中執(zhí)行一些邏輯,該邏輯就是向ChannelPipeline中添加一個(gè)新的ChannelHandler即ServerBootstrapAcceptor
  • 然后開(kāi)始將該Channel注冊(cè)到上述EventLoopGroup bossGroup中,該EventLoopGroup bossGroup會(huì)選擇內(nèi)部的一個(gè)EventLoop來(lái)執(zhí)行實(shí)際的注冊(cè)行為(這個(gè)時(shí)候就是當(dāng)前線程和操作的EventLoop不是同一個(gè)線程,即該過(guò)程是異步提交一個(gè)Runnable),一旦注冊(cè)完成,就執(zhí)行上述ChannelHandler的initChannel方法

至此,就完成了整個(gè)bind過(guò)程。一旦EventLoop內(nèi)部的Selector檢測(cè)到NioServerSocketChannel有新的連接到來(lái)的事件,則會(huì)交給NioServerSocketChannel的ChannelPipeline來(lái)處理,重點(diǎn)就是ChannelPipeline中的上述ServerBootstrapAcceptor,ServerBootstrapAcceptor做如下操作:

  • 1 為新的Channel的ChannelPipeline配置我們上述代碼中的childHandler指定的ChannelHandler
  • 2 將新的Channel注冊(cè)到了上述EventLoopGroup workerGroup中

sync介紹

bind方法返回的是一個(gè)ChannelFuture,從上面我們也知道該過(guò)程是異步的,sync方法則是一直等待到該異步過(guò)程結(jié)束。

再看下f.channel().closeFuture().sync()這個(gè)方法

每一個(gè)ChannelFuture都是和一個(gè)Channel綁定的,所以可以通過(guò)ChannelFuture來(lái)獲取對(duì)應(yīng)綁定的Channel對(duì)象

每一個(gè)Channel對(duì)象都有一個(gè)CloseFuture closeFuture對(duì)象,上述closeFuture方法并不是去執(zhí)行close方法而是獲取到這個(gè)CloseFuture closeFuture對(duì)象,然后調(diào)用它的sync方法即等待這個(gè)Future的結(jié)束。一般正常情況下是不會(huì)調(diào)用這個(gè)Future的結(jié)束方法的,只是在上述過(guò)程或者其他過(guò)程出現(xiàn)問(wèn)題的時(shí)候,如注冊(cè)到EventLoop失敗等才會(huì)去調(diào)用這個(gè)Feture的結(jié)束方法,所以正常情況下主線程會(huì)一直阻塞在CloseFuture closeFuture的sync方法上。

誤區(qū)

上述的bossGroup的創(chuàng)建問(wèn)題。

我們都知道bossGroup是用來(lái)accept連接,然后將連接綁定到workerGroup中的,一般情況下bossGroup設(shè)置線程數(shù)為1即可(基本只能為1),我們同時(shí)知道Ractor模型中可以使用多個(gè)Acceptor線程來(lái)執(zhí)行accept操作,加快accept的速度。

如果你想加快accept的速度,想開(kāi)啟多線程來(lái)accept,這時(shí)候想設(shè)置bossGroup的線程數(shù)為多個(gè)的話,就大錯(cuò)特錯(cuò)了,是根本沒(méi)效果的。

結(jié)合上面的原理,只有在bind端口的時(shí)候才會(huì)創(chuàng)建一個(gè)ServerSocketChannel,然后注冊(cè)到bossGroup內(nèi)部的一個(gè)EventLoop中,仍然是單線程負(fù)責(zé)ServerSocketChannel的accept工作,而bossGroup中的多線程僅僅是為bind多個(gè)端口服務(wù)的。

我們來(lái)看下tomcat是如何允許多個(gè)Acceptor線程來(lái)執(zhí)行accept操作的:

  • 1 創(chuàng)建了一個(gè)ServerSocketChannel serverSock,并bind到某個(gè)端口
  • 2 開(kāi)啟多個(gè)Acceptor線程,每個(gè)線程邏輯都是執(zhí)行上述serverSock的accept方法

沒(méi)有使用Selector來(lái)執(zhí)行accept操作,可以多線程并發(fā)執(zhí)行上述serverSock的accept方法。

一旦使用了Selector,基本上就相當(dāng)于將ServerSocketChannel serverSock綁定到了Selector所在線程上了(Selector不是線程安全的,只能在一個(gè)線程中被調(diào)度執(zhí)行)

4 后續(xù)

下一篇就要詳細(xì)描述下EventLoopGroup了。

以上就是分布式Netty源碼分析概覽的詳細(xì)內(nèi)容,更多關(guān)于分布式Netty源碼分析的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java 關(guān)鍵字super詳解及用法

    java 關(guān)鍵字super詳解及用法

    這篇文章主要介紹了java 關(guān)鍵字super詳解及用法的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java實(shí)現(xiàn)利用圖片或視頻生成GIF并發(fā)送微信

    Java實(shí)現(xiàn)利用圖片或視頻生成GIF并發(fā)送微信

    這篇文章主要為大家詳細(xì)介紹了Java語(yǔ)言如何利用圖片或視頻實(shí)現(xiàn)生成GIF并發(fā)送微信的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下
    2022-11-11
  • 淺談JVM之java class文件的密碼本

    淺談JVM之java class文件的密碼本

    一切的一切都是從javac開(kāi)始的。從那一刻開(kāi)始,java文件就從我們?nèi)庋劭煞直娴奈谋疚募?,變成了冷冰冰的二進(jìn)制文件。變成了二進(jìn)制文件是不是意味著我們無(wú)法再深入的去了解java class文件了呢?答案是否定的。本文將詳細(xì)介紹JVM之java class文件的密碼本。
    2021-06-06
  • Java?HashMap詳解及實(shí)現(xiàn)原理

    Java?HashMap詳解及實(shí)現(xiàn)原理

    Java?HashMap是Java集合框架中最常用的實(shí)現(xiàn)Map接口的數(shù)據(jù)結(jié)構(gòu),它使用哈希表實(shí)現(xiàn),允許null作為鍵和值,可以存儲(chǔ)不同類型的鍵值對(duì),在Java中,HashMap被廣泛應(yīng)用于各種場(chǎng)景,如緩存、數(shù)據(jù)庫(kù)連接池、路由器等,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-05-05
  • java使用Process調(diào)用exe程序及Process.waitFor()死鎖問(wèn)題解決

    java使用Process調(diào)用exe程序及Process.waitFor()死鎖問(wèn)題解決

    在編寫(xiě)Java程序時(shí),有時(shí)候我們需要調(diào)用其他的諸如exe,shell這樣的程序或腳本,下面這篇文章主要給大家介紹了關(guān)于java使用Process調(diào)用exe程序及Process.waitFor()死鎖問(wèn)題解決的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • MyBatis自定義TypeHandler如何解決字段映射問(wèn)題

    MyBatis自定義TypeHandler如何解決字段映射問(wèn)題

    這篇文章主要介紹了MyBatis自定義TypeHandler如何解決字段映射問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Spring事件監(jiān)聽(tīng)源碼解析流程分析

    Spring事件監(jiān)聽(tīng)源碼解析流程分析

    spring事件監(jiān)聽(tīng)機(jī)制離不開(kāi)容器IOC特性提供的支持,比如容器會(huì)自動(dòng)創(chuàng)建事件發(fā)布器,自動(dòng)識(shí)別用戶注冊(cè)的監(jiān)聽(tīng)器并進(jìn)行管理,在特定的事件發(fā)布后會(huì)找到對(duì)應(yīng)的事件監(jiān)聽(tīng)器并對(duì)其監(jiān)聽(tīng)方法進(jìn)行回調(diào),這篇文章主要介紹了Spring事件監(jiān)聽(tīng)源碼解析,需要的朋友可以參考下
    2023-08-08
  • spring中@autowired、@Qualifier、@Primary注解的使用說(shuō)明

    spring中@autowired、@Qualifier、@Primary注解的使用說(shuō)明

    這篇文章主要介紹了spring中@autowired、@Qualifier、@Primary注解的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring?Boot2.6.0新特性之默認(rèn)禁止循環(huán)引用

    Spring?Boot2.6.0新特性之默認(rèn)禁止循環(huán)引用

    Spring?Boot2.6.0為我們帶來(lái)很多好用的新特性/改進(jìn),這篇文章主要給大家介紹了關(guān)于Spring?Boot2.6.0新特性之默認(rèn)禁止循環(huán)引用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Java線程池ThreadPoolExecutor的使用及其原理詳細(xì)解讀

    Java線程池ThreadPoolExecutor的使用及其原理詳細(xì)解讀

    這篇文章主要介紹了Java線程池ThreadPoolExecutor的使用及其原理詳細(xì)解讀,線程池是一種多線程處理形式,處理過(guò)程中將任務(wù)添加到隊(duì)列,然后在創(chuàng)建線程后自動(dòng)啟動(dòng)這些任務(wù),線程池線程都是后臺(tái)線程,需要的朋友可以參考下
    2023-12-12

最新評(píng)論