Netty的源码里面有example,参照echo demo启动netty服务
public final class EchoServer {
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
public static void main(String[] args) throws Exception {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} else {
sslCtx = null;
}
//创建boss worker线程
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
final EchoServerHandler serverHandler = new EchoServerHandler();
try {
//创建netty服务端启动器
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)//给启动器配置boss worker
.channel(NioServerSocketChannel.class)//设置使用NioServerSocketChannel
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
//p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(serverHandler);
}
});
// Start the server.
ChannelFuture f = b.bind(PORT).sync();
// Wait until the server socket is closed.
f.channel().closeFuture().sync();
} finally {
// Shut down all event loops to terminate all threads.
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
可以看到创建启动服务,创建了EventLoopGroup bossGroup = new NioEventLoopGroup(1),那么我们先来看看NioEventLoopGroup的源码
上图红线圈住的就是NioEventLoopGroup的继承体系,下面来分析NioEventLoopGroup的创建过程
/**
* 默认的无参构造会调用参数是0的构造
*/
public NioEventLoopGroup() {
this(0);
public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory) {
this(nThreads, threadFactory, SelectorProvider.provider());
}
public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider,
final SelectStrategyFactory selectStrategyFactory) {
//调用父类构造
super(nThreads, executor, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
}
MultithreadEventLoopGroup的构造
/**
* @see MultithreadEventExecutorGroup#MultithreadEventExecutorGroup(int, Executor, Object...)
* 如果传进来的nThreads==0 就用 DEFAULT_EVENT_LOOP_THREADS
*/
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}
DEFAULT_EVENT_LOOP_THREADS 是什么呢?
private static final int DEFAULT_EVENT_LOOP_THREADS;
static {
//cpu核数*2
DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
"io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
if (logger.isDebugEnabled()) {
logger.debug("-Dio.netty.eventLoopThreads: {}", DEFAULT_EVENT_LOOP_THREADS);
}
}
在进入父类MultithreadEventExecutorGroup
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
}
//创建线程执行器,ThreadPerTaskExecutor的参数ThreadFactory适用于提供生产线程的工厂,
//每次执行任务都会创建一个线程实体
if (executor == null) {
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
//boss或者worker内部的具体执行者
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
//创建work的eventLoop
children[i] = newChild(executor, args);
success = true;
} catch (Exception e) {
// TODO: Think about if this is a good exception type
throw new IllegalStateException("failed to create a child event loop", e);
} finally {
.....
}
}
/**
* 创建线程选择器
* NioEventLoop(work) 新来一个连接 index++
* NioEventLoop(boss) 0 1 2 3 4
* →
*
* 线程选择器的优化,如果NioEventLoop(work) 线程个数是2的幂 2 4 8 16
* 那么返回一个PowerOfTwoEventExecutorChooser 否则 GenericEventExecutorChooser
*
* index++ & (len-1) index++ % (len-1)
*/
chooser = chooserFactory.newChooser(children);
.....
}
ThreadPerTaskExecutor的创建
public final class ThreadPerTaskExecutor implements Executor {
private final ThreadFactory threadFactory;
public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
if (threadFactory == null) {
throw new NullPointerException("threadFactory");
}
this.threadFactory = threadFactory;
}
/**
* 创建线程,执行runnable代码块
* @param command
*/
@Override
public void execute(Runnable command) {
threadFactory.newThread(command).start();
}
}
ThreadFactory 的newThread:
/**
* @param poolType NioEventLoopGroup
* @return 返回的 nioEventLoopGroup
*/
public static String toPoolName(Class<?> poolType) {
if (poolType == null) {
throw new NullPointerException("poolType");
}
//poolName MultithreadEventExecutorGroup
String poolName = StringUtil.simpleClassName(poolType);
switch (poolName.length()) {
case 0:
return "unknown";
case 1:
return poolName.toLowerCase(Locale.US);
default:
if (Character.isUpperCase(poolName.charAt(0)) && Character.isLowerCase(poolName.charAt(1))) {
return Character.toLowerCase(poolName.charAt(0)) + poolName.substring(1);
} else {
return poolName;
}
}
}
public DefaultThreadFactory(String poolName, boolean daemon, int priority, ThreadGroup threadGroup) {
if (poolName == null) {
throw new NullPointerException("poolName");
}
if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
throw new IllegalArgumentException(
"priority: " + priority + " (expected: Thread.MIN_PRIORITY <= priority <= Thread.MAX_PRIORITY)");
}
/**
* 线程name nioEventLoopGroup '-' 第几个eventLoop '-' 当前eventLoop中的第几个线程
*
* poolId是一个静态的
*/
prefix = poolName + '-' + poolId.incrementAndGet() + '-';
this.daemon = daemon;
this.priority = priority;
this.threadGroup = threadGroup;
}
主要就是thread的prefix的处理
@Override
public Thread newThread(Runnable r) {
Thread t = newThread(FastThreadLocalRunnable.wrap(r), prefix + nextId.incrementAndGet());
try {
if (t.isDaemon() != daemon) {
t.setDaemon(daemon);
}
if (t.getPriority() != priority) {
t.setPriority(priority);
}
} catch (Exception ignored) {
// Doesn't matter even if failed to set.
}
return t;
}
/**
* @param r
* @param name nioEventLoopGroup-2-1
* @return
*/
protected Thread newThread(Runnable r, String name) {
return new FastThreadLocalThread(threadGroup, r, name);
}
FastThreadLocalThread这是一个继承Thread的类,内部维护了一个map,保存线程局部变量使用
children = new EventExecutor[nThreads]在回头看NioEventLoop的创建newChild(executor, args)
io.netty.channel.nio.NioEventLoopGroup#newChild
@Override
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
//this NioEventLoopGroup executor 线程执行器,每次都会创建一个新的线程
return new NioEventLoop(this, executor, (SelectorProvider) args[0],
((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
}
chooser = chooserFactory.newChooser(children)
创建线程选择器
@Override
public EventExecutorChooser newChooser(EventExecutor[] executors) {
//判断是否是2的次方
if (isPowerOfTwo(executors.length)) {
return new PowerOfTwoEventExecutorChooser(executors);
} else {
return new GenericEventExecutorChooser(executors);
}
}
这里又一个优化的地方就是,创建EventExecutorChooser的具体实现类的时候是根据executors的length来决定的,netty为了优化也是够丧心病狂的
/** * 创建线程选择器 * NioEventLoop(work) 新来一个连接 index++ * NioEventLoop(boss) 0 1 2 3 4 * → * * 线程选择器的优化,如果NioEventLoop(work) 线程个数是2的幂 2 4 8 16 * 那么返回一个PowerOfTwoEventExecutorChooser 否则 GenericEventExecutorChooser * * index++ & (len-1) index++ % (len-1) */
PowerOfTwoEventExecutorChooser
private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@Override
public EventExecutor next() {
//使用位&操作符来觉得当前任务选用那个NioEventLoop
//executors就是NioEventLoopGroup中创建的NioEventLoop数组(具体的执行操作者)
return executors[idx.getAndIncrement() & executors.length - 1];
}
}
GenericEventExecutorChooser
private static final class GenericEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
GenericEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@Override
public EventExecutor next() {
//不是2的次方 那么就取模来决定当前任务选用那个NioEventLoop
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}
}
再来看NioEventLoopGroup的几个方法
io.netty.util.concurrent.MultithreadEventExecutorGroup#newDefaultThreadFactory
protected ThreadFactory newDefaultThreadFactory() {
return new DefaultThreadFactory(getClass());
}
前面已经说过创建线程的生产工厂,最后返回FastThreadLocalThread
io.netty.util.concurrent.MultithreadEventExecutorGroup#next
@Override
public EventExecutor next() {
return chooser.next();
}
根据上面对线程选择器的说明,这里会去children NioEventLoop[]中去拿到运算之后的NioEventLoop并返回
下一篇分析NioEventLoop的执行逻辑