当前位置: 首页 > 知识库问答 >
问题:

异步Netty HttpServer和HttpClient

曹景铄
2023-03-14

在过去的几天里,我一直在探索Netty,因为我正在编写一个快速而紧凑的HTTP服务器,它应该能够接收大量请求,而Netty的HTTP服务器实现非常简单,可以完成这项工作。

我的下一步是作为请求处理的一部分,我需要启动一个到外部web服务器的HTTP请求。我的直觉是实现一个可以同时发送大量请求的异步客户机,但我有点困惑什么是正确的方法。我的理解是,Netty服务器对每个传入消息都使用一个工作线程,因此在处理程序完成其工作之前,该工作线程不会被释放以接受新消息。这里有一个要点:即使我手头有一个异步HTTP客户机,我是否需要等待每个响应并用我的服务器处理程序将其处理回也无关紧要——相同的工作线程将一直处于阻塞状态。另一种方法是使用客户机的异步特性,快速返回未来对象以释放线程并放置侦听器(这意味着我必须向客户机返回200或202状态),并检查我的未来对象以指示何时收到响应,以及我可以将其推送到客户机。

这有意义吗?我是否偏离了我的假设?实现这种具有高并发性的Netty acceptor server外部客户端的良好实践是什么?

谢谢,

共有1个答案

上官琦
2023-03-14

假设你问的是内蒂4号。

配置了ServerBootstrap的Netty将具有固定数量的工作线程,用于接受请求并执行通道,如下所示:

Two threads accepting / processing requests
bootstrap.group(NioEventLoopGroup(2))

One thread accepting requests, two threads processing.
bootstrap.group(NioEventLoopGroup(1), NioEventLoopGroup(1))

在您的例子中,您有一个通道,包括一堆Http编解码器解码/编码内容和您自己的处理程序,该处理程序本身发出一个传出Http请求。你是对的,你不想阻止服务器接受传入的请求,或解码传入的Http消息,你可以做两件事来缓解这种情况,你已经找到了第一件事。

首先,您希望使用一个Async netty客户端来发出传出请求,让侦听器在传出请求返回时将响应写入原始请求通道。这意味着您不会阻塞和等待,这意味着您可以处理比处理这些请求的线程数更多的并发传出请求。

其次,您可以让自定义处理程序在其自己的EventExecutorGroup中运行,这意味着它在与acceptor/http编解码器通道处理程序不同的线程池中运行,如下所示:

// Two separate threads to execute your outgoing requests..
EventExecutorGroup separateExecutorGroup new DefaultEventExecutorGroup(2);

bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
    @Override
    public void initChannel(SocketChannel ch) {
        ChannelPipeline pipeline = ch.pipeline();
        .... http codec stuff .... 
        pipeline.addLast(separateExecutorGroup, customHandler);
    }
};

这意味着您的传出请求不会占用将用于接受/处理传入请求的线程。

 类似资料:
  • 异步操作在线程中执行,与主应用程序线程分开。当应用程序调用方法异步执行操作时,应用程序可以在异步方法执行其任务时继续执行。 示例 下面通过一个例子来理解这个概念。在示例程序中使用IO库接受用户输入。 是一种同步方法。它将阻止执行函数调用之后的所有指令,直到方法完成执行。 等待输入。它停止执行并且在收到用户输入之前不再执行任何操作。 以上示例将产生以下输出 - 在计算中,当某个事件在继续之前等待事件

  • 问题内容: 同步和异步AJAX调用有什么区别?何时使用同步以及何时异步? 问题答案: 在最基本的级别上,当您希望调用在后台发生时,您可以使用异步模式,而当您希望代码等待直到调用完成时,则可以使用同步模式。 异步模式是AJAX调用的常用方法,因为通常在事件上附加一个回调函数,以便您可以在服务器端数据就绪时进行响应,而不必等待数据到达。

  • 问题内容: 我正在尝试2种方法来阻止无限循环运行: supervisor_1 :任务编程取消 Supervisor_2 :使用Ctrl + C停止任务 虽然 supervisor_2 不会引发中断时,在任何错误,我不能让 supervisor_1 从得到。知道为什么吗? 这是代码: @update : 感谢@Gerasimov,这是一个可以解决此问题的版本,但仍会不时在KeyboardInterr

  • 本文向大家介绍举例说明同步和异步相关面试题,主要包含被问及举例说明同步和异步时的应答技巧和注意事项,需要的朋友参考一下 考察点:线程 如果系统中存在临界资源(资源数量少于竞争资源的线程数量的资源),例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就必须进行同步存取(数据库操作中的排他锁就是最好的例子)。当应用程序在对象上调用了一个需要花费很长时间来

  • 异步迭代允许我们对按需通过异步请求而得到的数据进行迭代。例如,我们通过网络分段(chunk-by-chunk)下载数据时。异步生成器(generator)使这一步骤更加方便。 首先,让我们来看一个简单的示例以掌握语法,然后再看一个实际用例。 回顾可迭代对象 让我们回顾一下可迭代对象的相关内容。 假设我们有一个对象,例如下面的 range: let range = { from: 1, to

  • 支持Python异步。包括对Core和ORM使用的支持,使用了异步兼容的方言。 1.4 新版功能. 注解 从SQLAlChemy 1.4.3开始的异步扩展现在可以被认为是 测试级 软件。API细节可能会更改,但是在这一点上,不太可能有重大的向后不兼容更改。 参见 对内核和ORM的异步IO支持 -初始功能发布 异步集成 -示例脚本演示了asyncio扩展中核心和ORM使用的工作示例。 Asyncio