这里罗列了一些比较重要的类名称及其对应的主要功能说明,以便于大家在阅读源码时可以快速了解对应类的功能:
| 类 | 作用 |
| — | — |
| ServerBootstrap | 服务端启动辅助类 |
| NioEventLoop | Nio事件处理器(Reactor模型) |
| NioEventLoopGroup | 一组Nio事件处理器(Reactor模型) |
在Netty
源码包中,我们首先看下 io.netty.example.echo
包中的EchoServer
类,该类中包含了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;
}
//处理连接事件
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
//处理读以及写的事件
EventLoopGroup workerGroup = new NioEventLoopGroup();
final EchoServerHandler serverHandler = new EchoServerHandler();
try {
//服务引导类
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
//初始化channel.pipeline
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
//p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(serverHandler);
}
});
// 启动服务,绑定端口
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();
}
}
}
在启动Netty
服务过程中,创建了两个EventLoopGroup
对象,这两个对象是Netty
的核心对象,其中bossGroup
用于接收请求,workerGroup
用于处理请求。如下所示:
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
我们可以看下NioEventLoopGroup
的类继承结构情况,如下所示:
从上图可知,NioEventLoopGroup
实现了ScheduledExecutorService
接口,因此它可以实现定时任务相关的功能。同时它还继承了SingleThreadEventExecutor
类,从类名可以看出,这是一个单线程的线程执行器。在Netty
中,通过NioEventLoopGroup
的创建来达到创建NioEventLoop
的目的。通过有参参数构建NioEventLoopGroup
对象,实际调用的是MultithreadEventExecutorGroup
的构造方法,如下所示:
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object… args) {
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format(“nThreads: %d (expected: > 0)”, nThreads));
}
if (executor == null) {
//ewDefaultThreadFactory()会创建一个线程工厂,该线程工厂的作用就是用来创建线程,同时给线程设置名称:nioEventLoop-1-XX
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
// 根据传进来的线程数,来创建指定大小的数组大小,这个数组就是用来存放NioEventLoop对象实例
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
//异常标志
boolean success = false;
try {
创建nThreads个nioEventLoop保存到children数组中
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 {
//异常处理
if (!success) {
for (int j = 0; j < i; j ++) {
children[j].shutdownGracefully();
}
for (int j = 0; j < i; j ++) {
EventExecutor e = children[j];
try {
while (!e.isTerminated()) {
e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
}
} catch (InterruptedException interrupted) {
// Let the caller handle the interruption.
Thread.currentThread().interrupt();
break;
}
}
}
}
}
// 通过线程执行器选择工厂来创建一个线程执行器
chooser = chooserFactory.newChooser(children);
final FutureListener terminationListener = new FutureListener() {
@Override
public void operationComplete(Future future) throws Exception {
if (terminatedChildren.incrementAndGet() == children.length) {
terminationFuture.setSuccess(null);
}
}
};
for (EventExecutor e: children) {
e.terminationFuture().addListener(terminationListener);
}
Set childrenSet = new LinkedHashSet(children.length);
Collections.addAll(childrenSet, children);
readonlyChildren = Collections.unmodifiableSet(childrenSet);
}
对应的参数解析,如下表所示:
| 参数 | 说明 |
| — | — |
| nThreads | 创建的线程数量 |
| executor | 线程执行器(用户可自定义,没有则为null,后续进行初始化) |
| chooserFactory | 事件执行选择工厂 |
EventLoopGroup
在创建的时候会调用NioEventLoop
中的openSelector()
方法。
EventLoopGroup
创建本质就是创建多个NioEventLoop
,这里创建NioEventLoop
就是初始化一个Reactor
,包括selector
和taskQueue
。
NioEventLoop
源码如下:
public final class NioEventLoop extends SingleThreadEventLoop {
…
private SelectorTuple openSelector() {
final Selector unwrappedSelector;
try {
unwrappedSelector = provider.openSelector();
} catch (IOException e) {
throw new ChannelException(“failed to open a new selector”, e);
}
if (DISABLE_KEY_SET_OPTIMIZATION) {
return new SelectorTuple(unwrappedSelector);
}
Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Object run() {
try {
return Class.forName(
“sun.nio.ch.SelectorImpl”,
false,
PlatformDependent.getSystemClassLoader());
} catch (Throwable cause) {
return cause;
}
}
});
if (!(maybeSelectorImplClass instanceof Class) ||
// ensure the current selector implementation is what we can instrument.
!((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) {
if (maybeSelectorImplClass instanceof Throwable) {
Throwable t = (Throwable) maybeSelectorImplClass;
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
**
[外链图片转存中…(img-m39lZYk3-1715854578054)]
[外链图片转存中…(img-dIowYqxm-1715854578055)]
[外链图片转存中…(img-lIoudnir-1715854578055)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!