服务端_说说Netty服务端启动流程
本文來源:http://yeming.me/2016/03/12/netty1/
netty服務端代碼分析
服務端啟動配置
對于 ServerBootstrap:ServerBootstrap繼承于 AbstractBootstrap,它從父類繼承了 EventLoopGroupgroup, ChannelFactoryextendsC>channelFactory,自己新增了 EventLoopGroupchildGroup, ChannelHandlerchildHandler。上面 b.group開始的鏈式代碼就是初始化上面這些屬性的值的。
bossgroup和 workergroup:可以看到都是 NioEventLoopGroup,可以理解成2個線程池。從 bossgroup中隨便選一個作為 Reactor模型中的 acceptor,監聽客戶端連接,創建 socketChannel,然后從 workergroup選取一個io線程來處理 socketChannel的讀取事件。
對于 NioEventLoopGroup和 NioEventLoop:先看下類圖
可以看到 NioEventLoopGroup繼承了 EventLoopGroupNioEventLoop實現了EventLoop,而EventLoop又繼承自EventLoopGroup。eventloopgroup.next()又可以返回一個eventloop。可以看到EventLoop最終繼承于線程池Executor。而最終NioEventLoopGroup又實現了EventLoop,接下來我們還會分析下NioEventLoopGroup
服務端注冊感興趣事件和監聽端口
注冊感興趣事件
b.bind最終調用到AbstractBootstrop的以下方法
final ChannelFuture initAndRegister() {
this.group().register(channel);(中間省略)
}
這個this.group就是一開始設置的bossgroup(NioEventLoopGroup),看到這個方法基本可以想到這個應該是把channel注冊到某個選擇器上
MultithreadEventLoopGroup
public ChannelFuture register(Channel channel) {
return this.next().register(channel);
}
上面的類圖已經可以看出 NioEventLoopGroup繼承自 MultithreadEventLoopGroup,最終 this.next()又會返回 NioEventLoop,所以也就是可以理解是把 channel注冊到 NioEventLoop上(我們猜想 NioEventLoop可以想象成封裝了一個 selector)
this.next()返回 NioEventLoop繼承于 SingleThreadEventLoopchannel.unsafe().register(this,promise);最終調用到 AbstractUnsafe的 register方法
eventLoop.execute(new OneTimeTask() {
public void run() {
AbstractUnsafe.this.register0(promise);
}
});
這里通過 bossgroup啟動一個線程
最終調用到
protected void doRegister() throws Exception {
boolean selected = false;
while(true) {
try {
this.selectionKey = this.javaChannel().register(this.eventLoop().selector, 0, this);
return;
} catch (CancelledKeyException var3) {
if(selected) {
throw var3;
}
this.eventLoop().selectNow();
selected = true;
}
}
}
監聽端口
可以看到第四張截圖
ChannelFuture regFuture = this.initAndRegister();
if(regFuture.cause() != null) {
return regFuture;
} else if(regFuture.isDone()) {
doBind0(regFuture, channel, localAddress, promise1); return promise1;
} else {
AbstractBootstrap.doBind0(regFuture, channel, localAddress, promise); } }); return promise;
}
可以看到 initAndRegister()這個方法就是上面我們說的注冊感興趣的事件。后面的 elseif和 else都有 dobind0 方法,這個方法也是通過之前的線程池啟動一個線程去監聽一個端口。
參考
netty api說明http://www.boyunjian.com/javadoc/io.netty/netty-transport/4.0.0.Alpha7//io/netty/channel/DefaultChannelFuture.htmlNetty 4源碼解析:服務端啟動http://blog.csdn.net/dc726/article/details/47858077Netty 4源碼解析:請求處理http://blog.csdn.net/dc726/article/details/48084367Netty系列之Netty線程模型(http://www.infoq.com/cn/articles/netty-threading-model?utmsource=infoq&utmmedium=popularlinks_homepage
●?Spring IOC流程清楚不?聊聊看
●?面試官:ScheduleThreadPoolExecutor了解不?
●?配置中心只有Apollo么?看看點評的Lion
●?面試官說從源碼角度說說Java線程池
●?JedisPool連接池相關配置
●?Hystrix初探
●?別再關注刪庫跑路了,談談數據庫架構
●?那些年非常火的MyCAT是什么?
●?Java14帶來了許多新功能
●?關于爛代碼的那些事(上)
●?關于整潔代碼的那些事(中)
●?關于整潔代碼的那些事(下)
●?面試官說Spring AOP 實現原理給我說說
●?深入理解JVM - 方法調用
●?Spring Boot神操作-多個數據源Service層封裝
●?Lombok經常用,但是你知道它的原理是什么嗎?
總結
以上是生活随笔為你收集整理的服务端_说说Netty服务端启动流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: excel打开空白_啥?下载的文件显示“
- 下一篇: crc java_java实现CRC16