解密Netty框架 | 从宏观的角度再一次认识与了解Netty
Netty介绍
Netty是互联网公司非常流行的Java开源网络框架,可以帮助用户快速开发高性能、高稳定的网络通信服务。Netty是互联网中间件、大数据领域使用最广泛、最核心的网络通信框架,比如:RocketMQ、Dubbo、Flink等等都在使用Netty来构建底层的网络通信服务。
本篇论述
本篇文章为解密Netty框架的第一篇,主要是从宏观的角度再一次认识与了解一下Netty,主要关注点在于Netty的线程模型、Netty是如何处理海量连接的、EventLoop的构成以及需要处理哪些工作、BossEventLoop与WorkerEventLoop的区别与联系,这些内容将会在本篇文章中一一呈现。
Netty逻辑视图
// Configure the server.
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<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
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();
}
以上这块代码是Netty提供的一段构建服务端程序的示例,这段代码相信大家都已经比较熟悉了。这里不做过多的解释。
当这段代码执行完成以后,Netty构建了一个怎样的逻辑视图呢,我们以图示的方式展示一下,帮助读者更好的理解这段内容。
1.BossEventLoop开始监听客户端的连接。当有新的连接到来时,将监听到原生JDK的 SocketChannel封装成Netty的NioSocketChannel。
2.由Netty的线程模型可知,workerEventLoop可能存在多个,默认为Cpu的核数,BossEventLoop线程将监听到的客户端连接按照既定的选择算法选中其中一个workerEventLoop,将其注册上去,并监听读写事件。
3.NioSocketChannel上面的读事件将会被workerEventLoop轮询到,并将读取到的数据依次调用ChannelPipeLine中的channelHandler,然后写回客户端。
EventLoop逻辑视图
经过上面的论述,我们一直在提到一个叫做EventLoop的东西,不管是BossEventLoop还是WorkerEventLoop。那么接下来,我们以图示的方式,展示一下EventLoop的逻辑视图。
可以看到,一个eventLoop的构成是由:
1.一个 Java thread
2.一个 Jdk Nio selector
3.Netty各种类型的内部队列
一个eventLoop就可以看做一个java的线程,由这个java线程驱动着这个EventLoop的运行。Netty整个框架的运转就是围绕着一个个的EventLoop。
BossEventLoop与WorkerEventLoop本质上都是一样的构成,只不过BossEventLoop上的selector注册的是Accept事件,主要监听客户端的连接,而WorkerEventLoop注册的是OP_READ|OP_WRITE 读写事件,专注于处理客户端连接的读写。
EventLoop运行逻辑
本模块我们主要介绍一下由单独线程驱动的EventLoop主要在做哪些事情。
eventLoop主要做了两件事情:
1.轮询IO事件并且处理对应的IO事件
2.执行任务队列的任务,其中任务队列分为三类,一类是定时的调度队列,内部的实现是一个优先级的队列,用于执行定时或者延迟任务。一类是普通任务队列,用于执行用户调用指定方法放进去的任务。一类是尾部的队列,用户执行一些优先级不高的任务,比如统计类型的。
另一点要提的就是EventLoop避免了JDK空轮训的BUG,解决的思路就是计数器+轮询阻塞的时间差来判断。发现陷入了JDK空轮训的BUG,则重新构建selector。
本期结尾
本篇作为Netty系列的第一篇,主要是从宏观的角度梳理了一下Netty的核心知识点。在内容上采用了图文并茂的方式,有助于帮助读者更好的理解Netty相关的知识点。
接下来,本系列还会带来更多关于Netty框架的解析,感谢大家的阅读与支持。
转载自:https://juejin.cn/post/7171066432510230536