参考文献:极客时间傅健老师的《Netty源码剖析与实战》Talk is cheap.show me the code!

什么是Reactor及三种版本

   反应堆设计模式(Reactor pattern):是一种为处理并发服务请求,并将请求提交到一个或者多个服务处理程序的事件设计模式。当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有的请求,然后派发这些请求至相关的工作线程进行处理。

  三种版本:Reactor单线程(一个人包揽),Reactor多线程模式(多人分担),主从Reactor多线程模式(多人细工分担)。

Reactor是一种开发模式,模式的核心流程为:注册感兴趣的事件---->扫描是都有感兴趣的事件发生---->事件发生后做出相应的处理。

  对于每一种的SocketChannel它监听的事件也不同,如下图!

Netty如何支持三种Reactor-LMLPHP

如何在Netty中使用Reactor模式

  Netty如何支持三种Reactor-LMLPHP

  上图中非主从Reactor多线程模式中"EventLoopGroup eventGroup = new NioEventLoopGroup()"中没有给参数,参考Reactor单线程模式给的参数是1,这里没有参数为什么是多线程模式?那是因为如果我们不去设置的话,它会根据CPU核数去计算出一个最优的线程数,现在单核CPU几乎没有了,所以现在几乎可以百分百的肯定这样就是多线程模式。

源码解释

public class MyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap sb = new ServerBootstrap();
sb.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(new MyServerHandler());
}
});
ChannelFuture f = sb.bind(8090).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}

  代码中标粗标大的就是主从Reactor模式的核心点,其中bossGroup(可以理解为主)和workerGroup(可以理解为从)都是需要被设置到ServerBootstrap中去,“sb.group(bossGroup,workerGroup)”则是绑定,进入group()方法:

public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
super.group(parentGroup);
ObjectUtil.checkNotNull(childGroup, "childGroup");
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}

进入super.group(parentGroup);

Netty如何支持三种Reactor-LMLPHP

可以看到"this.group = group”;group则是传入的“bossGroup”;this.group则是该类定义的成员。

volatile EventLoopGroup group;

而该成员在group()被return.

Netty如何支持三种Reactor-LMLPHP

接下来需要查看哪里调用了该方法(windows下的idea按ctrl+alt+h可以查询),如图:

Netty如何支持三种Reactor-LMLPHP

  图上标记的“ChannelFuture regFuture = config().group().register(channel);”不难看出我们取到了group,再将channel绑定进去,这里的channel指的是:在服务器的开发那就是ServerSocketChannel。所以可以简单的理解:我们将ServerSocketChannel绑定到bossGroup上,有了ServerSocketChannel就能创建子的SocketChannel,再将子的SocketChannel绑定到之前的workerGroup上。

源码验证

  还是之前的那张图,进入sb.group()中:

Netty如何支持三种Reactor-LMLPHP

这里的“this.childGroup = childGroup;”的this.childGroup 也是定义的成员

private volatile EventLoopGroup childGroup;

查看this.childGroup谁在用,搜索发现:

final EventLoopGroup currentChildGroup = childGroup;

Netty如何支持三种Reactor-LMLPHP

msg即SocketChannel,下面标红框的就是将msg进行绑定到workerGroup中,简单说就是两种SocketChannel绑定到两个Group里面去。这样就完成了主从Reactor模式的支持。

我只想做的更好,仅此而已

05-15 08:13