一、Netty服务端启动
先看下启动代码:
public final class NettyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// 启动类
ServerBootstrap b = new ServerBootstrap();
// ServerBootstrap就是一个Builder,使用Builder模式配置
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).handler(new SimpleServerHandler())
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
}
});
// 绑定端口号,开启服务
ChannelFuture f = b.bind(8888).sync();
f.channel().closeFuture().sync();
}
finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private static class SimpleServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelActive");
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelRegistered");
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("handlerAdded");
}
}
}
二、ServerBootstrap
先看下继承关系:

可见,ServerBootstrap是AbstractBootstrap的子类。AbstractBootstrap用于设置服务端NioServerSocketChannel,而ServerBootstrap用于设置为有新连接时新建的NioSocketChannel!用一张图说明两个类之间的关系如下:

三、NioEventLoop
Loop:循环,顾名思义,NioEventLoop肯定有个循环方法,而这个循环就在run()方法中,代码如下:
@Override
protected void run() {
for (;;) {
try {
switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {
case SelectStrategy.CONTINUE:// 默认实现下,不存在这个情况。
continue;
case SelectStrategy.SELECT:
//将wakenUp字段设置为false,标识当前状态为阻塞
// 1、调用select查询任务
select(wakenUp.getAndSet(false));
if (wakenUp.get()) {
selector.wakeup();
}
default:
}
cancelledKeys = 0;//已取消的key的数量
needsToSelectAgain = false;//是否需要再次选择
final int ioRatio = this.ioRatio;//IO比率
if (ioRatio == 100) {
try {
processSelectedKeys();//处理Channel 感兴趣的就绪 IO 事件
} finally {
runAllTasks();
}
} else {
final long ioStartTime = System.nanoTime();
try {
// 2、运行所有普通任务和定时任务,不限制时间
processSelectedKeys();//Channel 感兴趣的就绪 IO 事件
} finally {
final long ioTime = System.nanoTime() - ioStartTime;
// 3、运行所有普通任务和定时任务,限制时间
runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
}
}
} catch (Throwable t) {
handleLoopException(t);
}
try {
if (isShuttingDown()) {
closeAll();
if (confirmShutdown()) {
return;
}
}
} catch (Throwable t) {
handleLoopException(t);
}
}
}
NioEventLoop在Netty线程模型里做的哪些内容可以由下图的红圈得知:

NioEventLoop的处理逻辑可以参考下Tomcat中的NioEndpoint,二者有异曲同工之妙!NioEndpoint可以查看《Tomcat源码阅读(二)-请求处理流程》。
NioEventLoop在哪被调用的,请看下篇文章《Netty源码阅读(二)-Netty启动流程源码》
本文详细介绍了Netty服务端如何通过ServerBootstrap启动,并探讨了NioEventLoop的内部循环逻辑,包括处理IO事件和执行任务的过程。NioEventLoop在Netty线程模型中扮演关键角色,其工作方式类似于Tomcat的NioEndpoint。
1884

被折叠的 条评论
为什么被折叠?



