参考资料
NioEventLoopGroup源码分析
netty服务端启动流程源码分析
先看个流程图
服务端启动做了哪些事情
EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup(2);
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
channel = channelFactory.newChannel();
p.addLast(new ChannelInitializer<Channel>() {
@Override
public void initChannel(final Channel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
ChannelHandler handler = config.handler();
if (handler != null) {
pipeline.addLast(handler);
}
ch.eventLoop().execute(new Runnable() {
@Override
public void run() {
pipeline.addLast(new ServerBootstrapAcceptor(
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
});
ChannelFuture regFuture = config().group().register(channel);
eventLoop.execute(new Runnable() {
@Override
public void run() {
register0(promise);
}
});
private static void doBind0(
final ChannelFuture regFuture, final Channel channel,
final SocketAddress localAddress, final ChannelPromise promise) {
channel.eventLoop().execute(new Runnable() {
@Override
public void run() {
if (regFuture.isSuccess()) {
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} else {
promise.setFailure(regFuture.cause());
}
}
});
}
EventLoop的execute方法
public void execute(Runnable task) {
if (task == null) {
throw new NullPointerException("task");
}
boolean inEventLoop = inEventLoop();
if (inEventLoop) {
addTask(task);
} else {
startThread();
addTask(task);
if (isShutdown() && removeTask(task)) {
reject();
}
}
if (!addTaskWakesUp && wakesUpForTask(task)) {
wakeup(inEventLoop);
}
}
EventLoop的轮训方法
protected void run() {
for (;;) {
try {
switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {
try {
processSelectedKeys();
} finally {
final long ioTime = System.nanoTime() - ioStartTime;
runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
}
总结
1.启动流程中做的事情还是 创建selector,channel,绑定端口,轮训selector
其实和我们使用jdk nio编写一个网络编程是没本质区别的,只不过是做了组件化
的封装,扩展性更强
2.netty的EventLoop其实就像一个有一个线程的线程池,去轮训处理绑定在当前
EventLoop的所有channel的所有提交的任务,EventLoop也有拒绝策略,线程
工厂,任务队列等,只不过没有回收策略,这和他是一个具有NIO编程的强功能性
相关,注定是个长任务,而且也就一个线程,所以没必要