为什么我们真的需要多个 Netty boss 线程?

2024-04-16

我真的很困惑老板组的线程数量。我无法弄清楚我们需要多个老板线程的场景。在Boss 组是否需要多个线程? https://stackoverflow.com/questions/22280916/do-we-need-more-than-a-single-thread-for-boss-groupNetty 的创建者说,如果我们在不同的服务器引导程序之间共享 NioEventLoopGroup,多个 boss 线程会很有用,但我不明白其中的原因。

考虑这个简单的 Echo 服务器:

public class EchoServer {

private final int port;
private List<ChannelFuture> channelFutures = new ArrayList<ChannelFuture>(2);

public EchoServer(int port) {
    this.port = port;
}

public void start() throws Exception {

    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup(4);

    for (int i = 0; i != 2; ++i) {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class) // the channel type
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch)
                            throws Exception {
                        System.out.println("Connection accepted by server");
                        ch.pipeline().addLast(
                                new EchoServerHandler());
                    }
                });

        // wait till binding to port completes
        ChannelFuture f = b.bind(port + i).sync();
        channelFutures.add(f);
        System.out.println("Echo server started and listen on " + f.channel().localAddress());
    }

    for (ChannelFuture f : channelFutures)
        f.channel().closeFuture().sync();

    // close gracefully
    workerGroup.shutdownGracefully().sync();
    bossGroup.shutdownGracefully().sync();
}

public static void main(String[] args) throws Exception {
    if (args.length != 1) {
        System.err.println(
                "Usage: " + EchoServer.class.getSimpleName() +
                        " <port>");
        return;
    }
    int port = Integer.parseInt(args[0]);
    new EchoServer(port).start();
}

在上面的示例中,我创建了一个具有 1 个线程的 bossGroup 和一个具有 4 个线程的workerGroup,并将这两个事件组共享到绑定到两个不同端口(例如 9000 和 9001)的两个不同引导程序。以下是我的处理程序:

@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelRead(ChannelHandlerContext ctx,
                        Object msg)  throws Exception  {
    ByteBuf in = (ByteBuf) msg;
    System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8) + " from channel " + ctx.channel().hashCode());
    ctx.write(in);
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
    System.out.println("Read complete for channel " + ctx.channel().hashCode());
    // keep channel busy forever
    while(true); 
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx,
                            Throwable cause) {
    cause.printStackTrace();
    ctx.close();
}
}

在上面的处理程序中,我故意通过执行 while(true); 来保持通道忙碌。现在,如果我使用参数 9000 启动我的应用程序,它将创建两个绑定在端口 9000 和 9001 的服务器引导程序。

Echo server started and listen on /0:0:0:0:0:0:0:0:9090
Echo server started and listen on /0:0:0:0:0:0:0:0:9091

现在,如果我连接到两个端口并开始发送数据,则可以接收的最大连接数为 4,这是有道理的,因为我创建了 4 个工作线程并保持其通道繁忙而不关闭它:

echo 'abc' > /dev/tcp/localhost/9000
echo 'def' > /dev/tcp/localhost/9000
echo 'ghi' > /dev/tcp/localhost/9001
echo 'jkl' > /dev/tcp/localhost/9000
echo 'mno' > /dev/tcp/localhost/9001 # will not get connected

您还可以这样做:

telnet localhost 9000 -> then send data "abc"
telnet localhost 9000 -> then send data "def"
telnet localhost 9001 -> then send data "ghi"
telnet localhost 9000 -> then send data "jkl"
telnet localhost 9001 -> # will not get connected

我不明白的是,我有一个老板线程,并且我能够通过两个服务器引导程序连接到两个端口。那么为什么我们需要多个 boss 线程(默认情况下,boss 线程数为 2*num_logic_processors)?

Thanks,


Netty 的创建者表示,如果我们共享的话,多个 boss 线程会很有用 不同服务器引导程序之间的 NioEventLoopGroup,但我没有看到 其原因。

正如 Norman Maurer 所说,这不是必需的,但非常有用。

如果您将 1 个线程用于 2 个不同的引导程序,则意味着您无法同时处理与该引导程序的连接。因此,在非常非常糟糕的情况下,当主线程仅处理一个引导程序的连接时,永远不会处理与另一个引导程序的连接。

对于工人来说也是如此EventLoopGroup.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我们真的需要多个 Netty boss 线程? 的相关文章

随机推荐

  • 使用 jQuery 动态填写表单值

    我知道如何使用纯 PHP 执行此操作 但我需要在不重新加载页面的情况下执行此操作 无论如何 jQuery 是否可以有效地拉回一些数据库结果 基于用户在表单上的第一个文本字段中输入的内容 然后使用从数据库查询拉回的数据填充剩余的一些字段 本质
  • 运行 Jest 测试并收集特定目录中所有文件的覆盖率

    我正在使用以下代码对特定文件运行 Jest 测试 jest utils spec js collectCoverageFrom utils js 如果我想测试我使用的整个目录 jest someDirectory collectCovera
  • ...此内容也应该通过 HTTPS 加载

    再会 Site https mult privet com https mult privet com 在我的 Chrome 控制台中 我看到以下错误 blocked The page at https yandex st share ya
  • Vaadin Flow 应用程序自动在明暗模式之间切换

    Vaadin Flow 14 附带了两个捆绑主题的浅色和深色版本 Lumo and Material And now 浏览器可以向主机操作系统询问用户对浅色或深色模式的偏好 https stackoverflow com q 5084016
  • 返回空字符串或空值是否有更多优势?

    如果我正在编写以下方法 例如 那么以下方法是否被认为是良好的做法 A 如果文档不存在则返回空字符串 B 返回一个null value 做了很多 Java 工作 并且 Java 中的方法需要返回类型 我的印象是返回一致的类型是最佳实践 PHP
  • 使用 jquery UI 下一个按钮提交输入字段值,php 回显结果

    我当前正在使用 jquery ui 选项卡 仅适用于下一个 上一个按钮 和文本区域 我开发了一个 ajax js 函数 它将自动提交存储在文本区域中的值 并在 tab 2 中回显结果 但我目前想将自动提交表单的方法更改为当用户单击 下一步
  • 在 Xcode 4 中编译 Java

    我知道这个问题已经流传了很长时间 Xcode 4 中的 Java 我不需要任何建议 Eclipse Netbeans 例如 我只想在 XCode4 而不是 3 中编译一些简单的 Java 代码 我设法创建了一个文件 正如预期的那样 语法和一
  • 如何使 QPlainTextEdit 看起来像 .txt 文件?

    我有一个 QPlainTextEdit 它以表格形式显示一些信息 并且我添加了将其另存为 txt 文件的选项 我建了桌子漂亮的 https pypi python org pypi PrettyTable 当我打开 txt 文件时 它看起来
  • Android 平台中的推送通知

    我正在寻找编写一个从服务器接收推送警报的应用程序 我找到了几种方法来做到这一点 SMS 拦截传入的 SMS 并从服务器发起拉取 定期轮询服务器 每个都有其自身的局限性 短信 不保证到达时间 轮询可能会耗尽电池电量 请问您有更好的建议吗 非常
  • 再次:CSS、UL/OL:自定义计数器的缩进不正确

    我在中描述了我原来的问题这个线程 https stackoverflow com questions 16521330 css ul ol incorrect indent with custom counter 简而言之 当在 UL 中使
  • php 字符串转十六进制并带有 2 的补码:

    嗨 我有一根绳子193390663我想将其转换为hex with 2 s compliment 输出是0B86E847 现在我正在使用下面的功能 但它给了我313933333930363633 public static function
  • 为什么push指令会改变rsp的值? [复制]

    这个问题在这里已经有答案了 我正在检查 Ericksons Hacking The Art of Exploitation 中的这段代码片段 void test function int a int b int c int d int fl
  • JMS 客户端应用程序错误。无法使用 URL 连接

    我正在 C 上编写客户端应用程序以连接到我的本地 JMS Weblogic Server 12c 我尝试使用这里的示例代码 http docs oracle com cd E15523 01 web 1111 e13746 app exam
  • 创建和使用 Android 的 ContentProvider

    当我调用 Android ContentProvider 时 出现以下异常 java lang RuntimeException 无法 开始活动 ComponentInfo de harm android couchone de harm
  • 在水平列表上使用鼠标滚轮进行水平滚动

    我正在尝试使用鼠标滚轮进行水平滚动 但似乎不起作用 这是我的Fiddle http jsfiddle net a3j1x47a 我的主课 selector是一个可滚动的overflow 这是 JS 我正在尝试用它初始化滚动 selector
  • 如何使用quartz搜索pdf文档中的文本

    我正在使用quartz 来显示pdf 我需要获取搜索文本所在页面的索引 有人可以帮助我吗 谢谢 解决方案 有一个代码示例 用于从页面中提取文本并检查其序列 import
  • 在类中使用 requestAnimationFrame

    我不知道如何使用requestAnimationFrame在课堂上 这段代码工作正常 window onload function var width 20 function animation width var element docu
  • JUnit:如何按照 Spring 的预期访问 Spring 配置?

    有一个教程视频 http www infoq com presentations Mastering Spring MVC 3介绍了 Spring MVC 3 0 在演示项目中 他们使用以下目录结构
  • C++ 如何在删除前一个内容后使用同一行打印文本?

    我想打印一行 然后删除它 然后在同一行中打印另一行 我想要这个 因为我不会丢失或返回太多信息来获取在循环之前打印的信息 例如Processing file
  • 为什么我们真的需要多个 Netty boss 线程?

    我真的很困惑老板组的线程数量 我无法弄清楚我们需要多个老板线程的场景 在Boss 组是否需要多个线程 https stackoverflow com questions 22280916 do we need more than a sin