5

我有一个将一些消息放入 JMS 队列的第三方应用程序。我也有一个从这个队列中读取消息的应用程序。根据消息的类型,我将此消息保存到 DB 或将其发送到第三方服务。此外,我们不应该超过一些固定的每秒调用限制,以免第三方超载。

目前,对于这个用例,我想到了两种解决方案。

第一个是要求第三方发送一些自定义标头,以便 JMS 消费者能够使用 JMS 选择器过滤消息。因此,在这种情况下,我们将能够创建两个消费者,第一个将能够读取消息并将它们保存到数据库,第二个将使用一些节流/轮询机制在特定负载下向第三方发送消息. 但是这种方法对我不起作用,因为第三方添加这些自定义标题需要很长时间。在骆驼中是这样的:

from("jms:queue?selector=firstSelector")
    .bean(dbSaver);

from("jms:queue?selector=secondSelector")
    .throttle(10)
    .bean(httpClient);

第二个是创建另外两个 JMS 队列和一个将在这些队列之间拆分消息的处理器。然后与第一个解决方案中的逻辑相同。但是,这意味着应该添加 2 个额外的 JMS 队列。在骆驼中:

from("jms:parentQueue")
    .choice()
        .when(body().contains(...))
            .to("jms:fistChildQueue")
        .otherwise()
            .to("jms:secondChildQueue")
    .end()

from("jms:fistChildQueue")
    .bean(dbSaver);

from("jms:secondChildQueue")
    .throttle(10)
    .bean(httpClient);

另外,我一直在考虑使用两个内存队列而不是 JMS 队列。但是,在这种情况下,如果 JMS 队列中有很多消息,我们很容易陷入内存问题。

任何人都可以为这个用例建议一个架构设计吗?很高兴以骆驼路线风格看到它。

4

1 回答 1

2

1. Do you really need a queue for the flow to the DB? You could have bean(dbSaver) in the first route, or abstract it into a "direct" route instead of a jms-consuming route. This way, you have two queues instead of three.

2. A second approach: If you have control over the DB, you could write the second type of message to a different table. Then, an sql-consumer can poll for records, and delete them as it consumes them and passes them onward to the http service. However, the table is acting like a "roll your own Q". Probably more work for little payback, so maybe a second queue is better.

3. Finally, I wonder if you could reuse the same Queue. I see an option that will allow you to write back to the same queue. You could add a header and write back certain message. This could look confusing, and a bug could create an infinite loop.

If you already use JPA, this could be made a bit easier by using the camel-jpa component. As a consumer, it acts reads and deletes records (default behavior). I don't think the SQL/JDBC components have anything like that out of the box.

于 2016-08-10T20:44:03.443 回答