Now that we have a basic understanding of the components used at the bottom of Netty, we can see why Netty is an event-driven model. Netty’s Reactor model evolution and JDK NIO chat room implementation, next track down the Netty start source code, verify the Reactor model in Netty implementation
Example source: github.com/jsbintask22…
The sample
Let’s take the code that prints client information in section 1 as an example:
NioEventLoopGroup bossLoopGroup = new NioEventLoopGroup(1); / / 1
NioEventLoopGroup workLoopGroup = new NioEventLoopGroup(); / / 2
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossLoopGroup, workLoopGroup)
.channel(NioServerSocketChannel.class) / / 3
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { / / 9
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ByteBuf) {
System.out.println("client: "+ ((ByteBuf) msg).toString(StandardCharsets.UTF_8)); }}}); } }) .option(ChannelOption.SO_BACKLOG,128) / / 4
.childOption(ChannelOption.SO_KEEPALIVE, true); / / 5
ChannelFuture channelFuture = serverBootstrap.bind(port).addListener(f -> { / / 6
System.out.println("started.");
}).sync();
channelFuture.channel().closeFuture().addListener(future ->
System.out.println("DiscardServerApp.operationComplete")).sync(); / / 7
} finally {
bossLoopGroup.shutdownGracefully(); / / 8
workLoopGroup.shutdownGracefully();
}
Copy the code
Start the parsing
DiscardServer
- In a native
Selector
We create a new main thread (The main Reactor thread
) is used to loop over the Selector select operation and register itServerSocketChannel
In Netty, we call this threadboss
Thread, which corresponds to thisbossLoopGroup
Thread group, since we only need one ServerSocketChannel, we simply set the number of thread groups to 1 - In the native Selector, in order to prevent blocking the main thread, we use an alpha
8
An array of threadsReactor thread ___
) (Why eight?
), and it generates the same number of selectors that we have hereworkLoopGroup
Thread group, in Netty, the default number of threads isThe number of CPU cores * 2
;
While we haven’t introduced the NioEventLoopGroup yet, you probably already know that it is a thread pool:
ServerSocketChannel
NioServerSocketChannel
java.net.StandardSocketOptions
ChannelOption
The code for the key ServerSocketChannel initialization, Selector registration bound to a local port, and accept client is yet to be found. Let’s move on; Start tracing with serverbootstrap.bind (port) to see how they are initialized in the thread pool; First of all, to be sure, we already know that a connection in the underlying JDK abstraction is for Java. Nio. Channels. The Channel, in the netty, ty. It is encapsulated into io.net Channel. The Channel, The default channels in the following sections are Netty channels.
From the BIND trace, we can see two key steps:
initAndRegister
final ChannelFuture initAndRegister(a) {
Channel channel = null;
channel = channelFactory.newChannel(); / / 1
init(channel); / / 2
ChannelFuture regFuture = config().group().register(channel); / / 3
Copy the code
-
NioServerSocketChannel is generated using the channelFactory. It is easy to know that this channelFactory is generated by calling the default constructor using reflection based on our configured NioServerSocketChannel.
Ok, here we find the native JDK
ServerSocketChannel
And can be passedjavaChannel()
Method acquisition; -
After the channel is generated, initialization begins (setting parameters for ServerSocketChannel, etc.). It is worth noting here that there is a ChannelPipeline object in each channel (this object is described later, each channel corresponds to a pipeline, ServerBootstrapAcceptor), and then adds a handler to the pipeline. This handler is ServerBootstrapAcceptor, So when a new connection comes in, continue to register the new SocketChannel with the Selector.
-
Finally, a task is added to the boss thread:
So, the ServerSocketChannel is actively registering the Selector as well.
DoBind0: final call io.net ty. Channel. AbstractChannel. AbstractUnsafe bind method, finally the unsafe invokes the ServerSocket doBind method:
So far we’ve seen how the reactor main thread and IO subthreads in the native JDK correspond to netty, how a ServerSocketChannel is generated, registered with a Selector, and bound to a port. Now, there’s another key thing that we haven’t figured out, which is where the selector loop select is called, because we saw in the last chapter that it’s all about the selector;