Java 将HTTP请求/响应与RabbitMQ中的异步消息集成

Java 将HTTP请求/响应与RabbitMQ中的异步消息集成,java,rabbitmq,akka-http,Java,Rabbitmq,Akka Http,我们的应用程序是一个消息处理系统,有多个组件与RabbitMQ队列连接。因此,消息处理是异步的。现在我需要添加一个与系统通信的HTTP适配器。由于HTTP与请求/响应是同步的,所以我需要一种连接同步和异步流的方法。目前的解决办法是: HTTP请求被发送到一个队列。每个请求都有一个用于关联的唯一请求ID HTTP请求被CompletableFuture阻止 处理请求并将响应发送回另一个队列 队列使用者使用响应完成与请求ID的CompletableFuture匹配 HTTP适配器是使用Akka HT

我们的应用程序是一个消息处理系统,有多个组件与RabbitMQ队列连接。因此,消息处理是异步的。现在我需要添加一个与系统通信的HTTP适配器。由于HTTP与请求/响应是同步的,所以我需要一种连接同步和异步流的方法。目前的解决办法是:

  • HTTP请求被发送到一个队列。每个请求都有一个用于关联的唯一请求ID
  • HTTP请求被
    CompletableFuture
    阻止
  • 处理请求并将响应发送回另一个队列
  • 队列使用者使用响应完成与请求ID的
    CompletableFuture
    匹配
  • HTTP适配器是使用Akka HTTP实现的。使用
    handleWithAsyncHandler()
    和类型为
    function
    的函数处理请求

    问题是HTTP适配器需要管理所有挂起请求的映射(
    map
    )。对于每个请求,将创建一个新的
    CompletableFuture
    对象并将其放入映射中。当队列中收到响应时,匹配的
    CompletableFuture
    将完成以完成请求。这在代码中似乎是一种不好的味道,因为我需要仔细管理这个映射。例如,如果无法为请求生成响应,则需要从映射中删除该请求


    我想知道除了使用映射跟踪所有挂起的请求,是否还有其他方法。

    基本上,akka http可以是异步的。您不需要实现该队列来映射请求Id

    需要考虑的一点是,不要使用默认调度程序

    最好定义一个阻塞调度程序来处理CompletableFuture.SupplySync

    比如说

    my-blocking-dispatcher {
      type = Dispatcher
      executor = "thread-pool-executor"
      thread-pool-executor {
        fixed-pool-size = 16
      }
      throughput = 1
    }
    
    import static akka.http.javadsl.server.Directives.completeWithFuture;
    import static akka.http.javadsl.server.Directives.post;
    
    // GOOD (the blocking is now isolated onto a dedicated dispatcher):
    final Route routes = post(() -> {
        final MessageDispatcher dispatcher = system.dispatchers().lookup("my-blocking-dispatcher");
        return completeWithFuture(CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(5000L);
                    } catch (InterruptedException e) {
                    }
                    return HttpResponse.create()
                            .withEntity(Long.toString(System.currentTimeMillis()));
                }, dispatcher // uses the good "blocking dispatcher" that we
                // configured, instead of the default dispatcher to isolate the blocking.
        ));
    });
    
    

    虽然对于这个用例来说可能有点重,但是ApacheCamel能够相对轻松地完成这个确切的概念。对于最基本的用例,我想您可以用几行代码或XML配置将其连接起来。我认为这是有帮助的。