• Netty如何支持三种Reactor


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

    什么是Reactor及三种版本

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

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

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

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

    如何在Netty中使用Reactor模式

      

      上图中非主从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);

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

    volatile EventLoopGroup group;

    而该成员在group()被return.

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

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

    源码验证

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

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

    private volatile EventLoopGroup childGroup;

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

    final EventLoopGroup currentChildGroup = childGroup;

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

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

  • 相关阅读:
    记录下首次开通流量主,开心开心
    微信小程序之本地缓存
    在使用ef的情况下,有Migrations文件,想要直接生成数据库
    CSS 设置圆角div和阴影效果
    小程序UI库(UI组件)
    没有找到可以构建的 NPM 包---小程序开发
    php 接口参数对象转数组方法
    tp5框架获取随机n条
    php图片上传base64接口上传
    php如何实现定时任务,php定时任务方法,最佳解决方案,php自动任务处理
  • 原文地址:https://www.cnblogs.com/-qilin/p/11678769.html
Copyright © 2020-2023  润新知