服务端启动源码
文章目录
启动代码
public static void main(String[] args) throws Exception {
//创建两组eventLoop 一组用于客户端接入处理,另一个用于所有客户端
//其它事件处理.
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new RouterServerHandlerV2());
}
});
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();
}
}
1.配置EventLoopGroup,EventLoop
- 上面给ServerBootstrap添加两组eventLoop ,bossGroup 专门为客户端socket接入封装,并注册到workerGroup 事件线程组上,ServerSocketChannel是绑定到bossGroup 上的,SocketChannel被绑定到workerGroup;NioEventLoopGroup 默认线程数为cpu核数的2倍;bossGroup可据客户端接入并发量来设定线程,例如客户端接入并发量不大,可只设置一个线程数就行了
- NioEventLoopGroup 源码实现
public NioEventLoopGroup(int nThreads, Executor executor) {
//绑定单例SelectorProvider
this(nThreads, executor, SelectorProvider.provider());
}
public NioEventLoopGroup(
int nThreads, ThreadFactory threadFactory, final SelectorProvider selectorProvider) {
//绑定默认的Select 策略
this(nThreads, threadFactory, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
}
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
//如果没有设置线程数,则设备cpu 核 数的两倍
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}
protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {
//DefaultEventExecutorChooserFactory 轮询处理Executor 负载 ,实质相当于EventExecutor一个负载均衡器
this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args);
}
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
//省去一些代码
//ThreadPerTaskExecutor 只是简单实现Executor execute方法内new 一个组程并执行
if (executor == null) {
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
//据线程数设置eventLoop 数组大小
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
//创建子的EventLoop 这里根据实现,创建的是NioEventLoop
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 放入EventExecutor 负载均衡器
chooser = chooserFactory.newChooser(children);
//省去一些代码
}
//创建NioEventLopp
@Override
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
return new NioEventLoop(this, executor, (SelectorProvider) args[0],
((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
}
- NioEventLoop 源码实现
NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {
super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler);
if (selectorProvider == null) {
throw new NullPointerException("selectorProvider");
}
if (strategy == null) {
throw new NullPointerException("selectStrategy");
}
provider = selectorProvider;
//打开selector
final SelectorTuple selectorTuple = openSelector();
selector = selectorTuple.selector;
unwrappedSelector = selectorTuple.unwrappedSelector;
selectStrategy = strategy;
}
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
super.group(parentGroup);
if (childGroup == null) {
throw new NullPointerException("childGroup");
}
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}
2.配置Channel实现类型
//设置channel工厂
public B channel(Class<? extends C> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
}
//子channel处理器初始化回调
public ServerBootstrap childHandler(ChannelHandler childHandler) {
if (childHandler == null) {
throw new NullPointerException("childHandler");
}
this.childHandler = childHandler;
return this;
}
3.服务端绑定地址端口,并注册ServerSocketChannel
AbstractBootstrap
private ChannelFuture doBind(final SocketAddress localAddress) {
//注册nioServerSocketChannel 并注册到一个EventLoop上
final ChannelFuture regFuture = initAndRegister();
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {
return regFuture;
}
if (regFuture.isDone()) {
// At this point we know that the registration was complete and successful.
ChannelPromise promise = channel.newPromise();
doBind0(regFuture, channel, localAddress, promise);
return promise;
} else {
//省去一些代码
return promise;
}
}
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
//创建前面绑定的NioServerSocketChannel 类型的实例
//在创建channel同时已经给其配置了一个DefaultChannelPipeline
channel = channelFactory.newChannel();
//初始化channel信息
init(channel);
} catch (Throwable t) {
//省去一些代码
}
//给channe绑定eventloop(NioEventLoop)
ChannelFuture regFuture = config().group().register(channel);
return regFuture;
}
//初始化channel信息
@Override
void init(Channel channel) throws Exception {
final Map<ChannelOption<?>, Object> options = options0();
synchronized (options) {
setChannelOptions(channel, options, logger);
}
final Map<AttributeKey<?>, Object> attrs = attrs0();
synchronized (attrs) {
for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
@SuppressWarnings("unchecked")
AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
channel.attr(key).set(e.getValue());
}
}
//初始化所绑定的pipeline
ChannelPipeline p = channel.pipeline();
final EventLoopGroup currentChildGroup = childGroup;
final ChannelHandler currentChildHandler = childHandler;
final Entry<ChannelOption<?>, Object>[] currentChildOptions;
final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
synchronized (childOptions) {
currentChildOptions = childOptions.entrySet().toArray(newOptionArray(0));
}
synchronized (childAttrs) {
currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));
}
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() {
//ServerBootstrapAcceptor 传入子group ,用于接入客户接入时,给客户端channel绑定到该group去
pipeline.addLast(new ServerBootstrapAcceptor(
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
});
}
4.注册ServerSocketChannel 到EventLoop
- 绑定eventloop
SingleThreadEventLoop
@Override
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
promise.channel().unsafe().register(this, promise);
return promise;
}
AbstractUnsafe
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
//省去一些代码,设置当前channel的eventloop
AbstractChannel.this.eventLoop = eventLoop;
if (eventLoop.inEventLoop()) {
register0(promise);
} else {
try {
eventLoop.execute(new Runnable() {
@Override
public void run() {
register0(promise);
}
});
} catch (Throwable t) {
//
}
}
}
private void register0(ChannelPromise promise) {
try {
// check if the channel is still open as it could be closed in the mean time when the register
// call was outside of the eventLoop
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
boolean firstRegistration = neverRegistered;
//开始实质性注册到底层
doRegister();
neverRegistered = false;
registered = true;
//省去一些代码
}
AbstractNioChannel
注册到底层的nio去
@Override
protected void doRegister() throws Exception {
boolean selected = false;
for (;;) {
try {
// ServerSocketChannelImpl.regiest 这里是jdk里的实现了
selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
return;
} catch (CancelledKeyException e) {
//省略一些消息
}
}
}