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

分布式Netty源碼分析概覽

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

服務器端demo

看下一個簡單的Netty服務器端的例子

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();  
    }  
}

先來簡單說說上述遇到的類:

EventLoopGroup介紹

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

功能1:先來看看注冊Channel

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

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

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

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

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

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

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

ChannelPipeline介紹

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

bind過程

上述serverBootstrap的bind過程如下:

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

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

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

sync介紹

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

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

每一個ChannelFuture都是和一個Channel綁定的,所以可以通過ChannelFuture來獲取對應綁定的Channel對象

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

誤區(qū)

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

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

如果你想加快accept的速度,想開啟多線程來accept,這時候想設置bossGroup的線程數(shù)為多個的話,就大錯特錯了,是根本沒效果的。

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

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

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

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

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

4 后續(xù)

下一篇就要詳細描述下EventLoopGroup了。

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

    MyBatis自定義TypeHandler如何解決字段映射問題

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

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

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

    spring中@autowired、@Qualifier、@Primary注解的使用說明

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

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

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

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

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

最新評論