我应该使用什么消息传递模式来处理来自休息请求的 return 响应?

What messaging pattern should I use to process and return responses from a rest request?

我有一个与此类似的轴辐式架构:

GET 请求进入集线器并将其路由到其中一个分支进行处理。在集线器上,我还将请求放在一个带有 UUID 的映射中,这样当我从处理中取回数据时,我可以 return 做出正确的响应。辐条是相同的,用于平衡负载。然后,我需要将信息从分支传回集线器并 return 正确的响应。
我想使用 JMS 进行消息传递。

integration patterns 的最佳组合是什么?

好吧,如果我正确理解您的设计,这似乎是 request/reply 场景,因为辐条实际上返回了一些响应。如果不是,它将是 publish/subscribe.

您可以将 ActiveMQ 用于 jms 和 request/reply。看这里: http://activemq.apache.org/how-should-i-implement-request-response-with-jms.html

至于细节,这完全取决于您的要求,会立即发送响应还是需要很长的 运行 过程?

如果这是一个漫长的 运行 过程,您可以避免 request/reply 并使用即刻即弃的方案。

基本上,集线器会在一个队列上触发一条消息,该消息正被其中一个分支组件侦听。后端处理完成后,它 returns 对集线器监控的队列的响应。您可以通过一些 correlationId 关联 request/response。在请求部分,您可以将 correlationId 保存在缓存中以匹配响应。在 request/reply 场景中,这是由基础架构为您完成的,但不会用于较长的 运行 过程。

总结一下: 使用 ActiveMQ 通过 JMS 处理消息。 将 Camel 用于 REST 位。 如果您确定希望得到相当快的响应,请使用 request/reply。 如果您希望响应需要很长时间但必须匹配消息 correlationIds,请使用 fire and forget。

您在 Vert.x 中已经有 Request/Reply,因此您可以使用大约 20 行代码实现此行为:

public static void main(String[] args) {

    Vertx vertx = Vertx.vertx();

    Router router = Router.router(vertx);

    router.get("/").handler((request) -> {
        // When hub receives request, it dispatches it to one of the Spokes
        String requestUUID = UUID.randomUUID().toString();
        vertx.eventBus().send("processMessage", requestUUID, (spokeResponse) -> {
            if (spokeResponse.succeeded()) {
                request.response().end("Request " + requestUUID + ":" + spokeResponse.result().body().toString());
            }
            // Handle errors
        });
    });

    // We create two Spokes
    vertx.deployVerticle(new SpokeVerticle());
    vertx.deployVerticle(new SpokeVerticle());

    // This is your Hub
    vertx.createHttpServer().requestHandler(router::accept).listen(8888);
}

这是 Spoke 的样子:

/**
 * Static only for the sake of example
 */
static class SpokeVerticle extends AbstractVerticle {

    private String id;

    @Override
    public void start() {
        this.id = UUID.randomUUID().toString();

        vertx.eventBus().consumer("processMessage", (request) -> {
            // Do something smart

            // Reply
            request.reply("I'm Spoke " + id + " and my reply is 42");
        });
    }
}

尝试在 http://localhost:8888/

的浏览器中访问它

您应该看到每次都会生成请求 ID,而两个 Spokes 中只有一个响应您的请求。

如果您想将 Camel 与 JMS 一起使用,那么您应该使用 Request-Reply EIP, and as far as examples go, you have a pretty good one provided via Camel's official examples - 它可能有点旧,但仍然非常有效。

虽然您可以通过 Spring 忽略示例的 Camel 配置,但其路由定义提供了足够的信息:

public class SpokeRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        from("jms:queue:spoke")
            .process(e -> {
               Object result = ...; // do some processing
               e.getIn().setBody(result); // publish the result
        // Camel will automatically reply if it finds a ReplyTo and CorrelationId headers
            });
    }
}

然后 HUB 需要做的就是调用:

ProducerTemplate camelTemplate = camelContext.createProducerTemplate();
Object response = camelTemplate.sendBody("jms:queue:spoke", ExchangePattern.InOut, input);