开启一个服务端,端口绑定在port,使用nio模式
public class NettyDemoServer {
private final int port;
public NettyDemoServer(int port){
this.port = port;
}
public void start() throws Exception {
EventLoopGroup workgroup = new NioEventLoopGroup();
EventLoopGroup boosGroup = new NioEventLoopGroup(1);
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boosGroup,workgroup)
.channel(NioServerSocketChannel.class)
.localAddress(port)
.handler(new NettyDemoServerHandler())
.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel channel) throws Exception {
channel.pipeline().addLast(new NettyDemoServerHandler());
}
});
ChannelFuture future = bootstrap.bind().sync();
System.out.println(NettyDemoServer.class.getName() +" started and listen on " + future.channel().localAddress());
future.channel().closeFuture().sync();
}catch (Exception e){
workgroup.shutdownGracefully().sync();
boosGroup.shutdownGracefully().sync();
}
}
public class NettyDemoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.println("server received: " + in.toString(CharsetUtil.UTF_8));
ctx.write(msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
}
EventLoopGroup初始化
//处理IO事件
EventLoopGroup workgroup = new NioEventLoopGroup();
//处理TCP链接请求
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
构造函数
public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory,
final SelectorProvider selectorProvider, final SelectStrategyFactory selectStrategyFactory) {
super(nThreads, threadFactory, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
}
调用父类MultithreadEventLoopGroup的构造函数
protected MultithreadEventLoopGroup(int nThreads, ThreadFactory threadFactory, Object... args) {
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, threadFactory, args);
}
//设置默认的线程数
private static final int DEFAULT_EVENT_LOOP_THREADS;
static {
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的构造函数
做了三件事情:
1.产生了一个线程工场:threadFactory = newDefaultThreadFactory();
protected ThreadFactory newDefaultThreadFactory() {
return new DefaultThreadFactory(this.getClass()); //NioEventLoopGroup.class
}
2.选择策略:数组长度是2的幂次方,选择PowerOfTwoEventExecutorChooser,在选EventExecutor时使用children[idx.getAndIncrement() & executors.length - 1];如果数组长度不是2的幂次方,选择GenericEventExecutorChooser,children[Math.abs(idx.getAndIncrement() % executors.length)].
private final EventExecutor[] children;
children = new SingleThreadEventExecutor[nThreads];
if (isPowerOfTwo(this.children.length)) {
this.chooser = new MultithreadEventExecutorGroup.PowerOfTwoEventExecutorChooser();
} else {
this.chooser = new MultithreadEventExecutorGroup.GenericEventExecutorChooser();
}
3.产生nTreads个NioEventLoop对象保存在children数组中
this.children[i] = this.newChild(threadFactory, args);
//在NioEventLoopGroup重载
@Override
protected EventExecutor newChild(
ThreadFactory threadFactory, Object... args) throws Exception {
return new NioEventLoop(this, threadFactory, (SelectorProvider) args[0]);
}
追溯到SingleThreadEventExecutor:
1、利用ThreadFactory创建一个Thread,传入了一个Runnable对象,调用NioEventLoop类的run方法
2、使用LinkedBlockingQueue类初始化taskQueue :执行任务
protected SingleThreadEventExecutor(
EventExecutorGroup parent, ThreadFactory threadFactory, boolean addTaskWakesUp) {
...
thread = threadFactory.newThread(new Runnable() {
@Override
public void run() {
...
try {
SingleThreadEventExecutor.this.run();
success = true;
} catch (Throwable t) {
logger.warn("Unexpected exception from an event executor: ", t);
} finally {
...
}
}
});
taskQueue = newTaskQueue();
}
protected Queue<Runnable> newTaskQueue() {
return new LinkedBlockingQueue<Runnable>();
}
@Override
protected void run() {
for (;;) {
// 获取之前的线程状态,并让 select 阻塞
boolean oldWakenUp = wakenUp.getAndSet(false);
try {
// return !taskQueue.isEmpty();
if (hasTasks()) {
selectNow();
} else {
//1.首先轮询注册到NioEventLoop线程的selector上的所有的channel的IO事件
// 自旋进行等待可进行 select 操作
select(oldWakenUp);
//唤醒线程
if (wakenUp.get()) {
selector.wakeup();
}
}
cancelledKeys = 0;
needsToSelectAgain = false;
final int ioRatio = this.ioRatio;
//处理 selected 的通道的数据,并执行所有的任务
if (ioRatio == 100) {
//2.处理产生网络IO事件的channel
processSelectedKeys();
//3.处理任务队列
runAllTasks();
} else {
final long ioStartTime = System.nanoTime();
processSelectedKeys();
final long ioTime = System.nanoTime() - ioStartTime;
runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
}
if (isShuttingDown()) {
closeAll();
if (confirmShutdown()) {
break;
}
}
} catch (Throwable t) {
logger.warn("Unexpected exception in the selector loop.", t);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}}
4.children数组中每个EventExecutor绑定监听事件
terminatedChildren
final FutureListener<Object> terminationListener = new FutureListener<Object>() {
@Override
public void operationComplete(Future<Object> future) throws Exception {
if (terminatedChildren.incrementAndGet() == children.length) {
terminationFuture.setSuccess(null);
}
}
};
for (EventExecutor e: children) {
e.terminationFuture().addListener(terminationListener);
}
ServerBootstrap
服务端的一个启动辅助类,通过给他设置一系列参数来绑定端口启动服务
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boosGroup,workgroup).channel(NioServerSocketChannel.class).localAddress(port).childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel channel) throws Exception {
channel.pipeline().addLast(new NettyDemoServerHandler());
}
});
ServerBootstrap类参数
private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
private volatile EventLoopGroup childGroup; //workGroup
private volatile ChannelHandler childHandler; //new ChannelInitializer
父类AbstractBootstrap类参数
private volatile EventLoopGroup group; //boosGroup
private volatile ChannelFactory<? extends C> channelFactory;
private volatile SocketAddress localAddress; //port
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
private volatile ChannelHandler handler; //NettyDemoServerHandler()
group(boosGroup,workgroup)
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
super.group(parentGroup); //boosGroup
if (childGroup == null) {
throw new NullPointerException("childGroup");
}
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}
channel(NioServerSocketChannel.class)
设置父类属性channelFactory 为: BootstrapChannelFactory类的对象
public B channel(Class<? extends C> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
return channelFactory(new BootstrapChannelFactory<C>(channelClass));
}
public B channelFactory(ChannelFactory<? extends C> channelFactory) {
if (channelFactory == null) {
throw new NullPointerException("channelFactory");
}
if (this.channelFactory != null) {
throw new IllegalStateException("channelFactory set already");
}
this.channelFactory = channelFactory;
return (B) this;
}
private static final class BootstrapChannelFactory<T extends Channel> implements ChannelFactory<T> {
private final Class<? extends T> clazz;
BootstrapChannelFactory(Class<? extends T> clazz) {
this.clazz = clazz;
}
@Override
public T newChannel() {
try {
//通过反射来实例化NioServerSocketChannel.class
return clazz.newInstance();
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
@Override
public String toString() {
return StringUtil.simpleClassName(clazz) + ".class";
}
}
localAddress(port)
设置监听端口
public B localAddress(int inetPort) {
return localAddress(new InetSocketAddress(inetPort));
}
public B localAddress(SocketAddress localAddress) {
this.localAddress = localAddress;
return (B) this;
}
handler(new NettyDemoServerHandler())
设置父类 AbstractBootstrap的handle属性
public B handler(ChannelHandler handler) {
if (handler == null) {
throw new NullPointerException("handler");
}
this.handler = handler;
return (B) this;
}
public class NettyDemoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.println("server received: " + in.toString(CharsetUtil.UTF_8));
ctx.write(msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
childHandle
设置childHandler
public ServerBootstrap childHandler(ChannelHandler childHandler) {
if (childHandler == null) {
throw new NullPointerException("childHandler");
}
this.childHandler = childHandler;
return this;
}
启动服务
ChannelFuture future = bootstrap.bind().sync();
//AbstractBootstrap类
public ChannelFuture bind() {
validate();
SocketAddress localAddress = this.localAddress;
if (localAddress == null) {
throw new IllegalStateException("localAddress not set");
}
return doBind(localAddress);
}
private ChannelFuture doBind(final SocketAddress localAddress) {
//实例一个ChannelFuture
final ChannelFuture regFuture = initAndRegister();
//ChannelFuture通过反射产生一个NioServerSocketChannel类的实例
final Channel channel = regFuture.channel();
//异常检查
if (regFuture.cause() != null) {
return regFuture;
}
final ChannelPromise promise;
//绑定socket
if (regFuture.isDone()) {
promise = channel.newPromise();
doBind0(regFuture, channel, localAddress, promise);
} else {
promise = new PendingRegistrationPromise(channel);
regFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
doBind0(regFuture, channel, localAddress, promise);
}
});
}
return promise;
}
initAndRegister()
1、通过反射产生了一个NioServerSocketChannle对象
2、完成了channel初始化
3、将NioServerSocketChannel进行了注册
final ChannelFuture initAndRegister() {
//通过反射产生来一个NioServerSocketChannel类的实例
//在父类构造函数中SelectableChannel.configureBlocking(false);设置当前的ServerSocketChannel为非阻塞
final Channel channel = channelFactory().newChannel();
try {
init(channel);
} catch (Throwable t) {
channel.unsafe().closeForcibly();
//用来负责底层的connect、register、read和write等操作。
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
}
//调用了NioEventLoop对象中的register方法,把channel绑定到NioEventLoop
ChannelFuture regFuture = group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
AbstractBootstrap类
private static void doBind0(
final ChannelFuture regFuture, final Channel channel,
final SocketAddress localAddress, final ChannelPromise promise) {
// 提交一个Runnable任务到NioEventLoop线程中来进行处理
channel.eventLoop().execute(new Runnable() {
@Override
public void run() {
if (regFuture.isSuccess()) {
//调用AbstractChannel类的bind方法,实现channel与端口的绑定
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} else {
promise.setFailure(regFuture.cause());
}
}
});
}
追溯到NioServerSocketChannel:
//通过JDK调用channel socket的bind函数绑定服务器端口号
protected void doBind(SocketAddress localAddress) throws Exception {
if (PlatformDependent.javaVersion() >= 7) {
javaChannel().bind(localAddress, config.getBacklog());
} else {
javaChannel().socket().bind(localAddress, config.getBacklog());
}
}