您能以编程方式更改Java嵌入式代理中队列的"死信"处理吗?

Ste*_*ins 6 java multithreading activemq-classic jms apache-camel

背景

在高级别,我有一个Java应用程序,其中某些事件应该触发当前用户采取的某个操作.但是,事件可能非常频繁,并且操作始终相同.因此,当第一个事件发生时,我想在不久的将来安排行动(例如5分钟).在该时间窗口期间,后续事件不应采取任何操作,因为应用程序发现已经安排了一个操作.一旦计划的操作执行,我们将返回步骤1,下一个事件将再次开始循环.

我的想法是通过在应用程序本身内嵌入内存中的ActiveMQ实例来实现这种过滤和限制机制(我不关心队列持久性).

我相信JMS 2.0支持延迟传送的概念,延迟消息位于"暂存队列"中,直到传送到真实目的地为止.但是,我也相信ActiveMQ还不支持JMS 2.0规范......所以我正在考虑模仿生存时间(TTL)值和死信队列(DLQ)处理的相同行为.

基本上,我的消息生成器代码会将消息放在虚拟登台队列上,消费者从中没有任何东西.消息将以5分钟的TTL值放置,并在到期时ActiveMQ将它们转储到DLQ中. 这是我的消息消费者实际消费消息的队列.

我认为我不想实际使用"默认"DLQ,因为我不知道ActiveMQ可能在那里转储哪些与我的应用程序代码完全无关的内部事物.所以我认为我的虚拟登台队列最好有自己的自定义DLQ.我只看过一页讨论DLQ配置的ActiveMQ文档,它只针对独立的ActiveMQ安装(不是嵌入在应用程序中的内存代理)的XML配置文件.

是否可以在运行时以编程方式为嵌入式ActiveMQ实例中的队列配置自定义DLQ?

如果你认为我走错了路,我也有兴趣听听其他建议.我对JMS比AMQP更熟悉,所以我不知道Qpid或其他一些Java嵌入式AMQP代理是否更容易.无论Apache Camel究竟是什么(!),我相信它应该在这类事情上表现出色,但这种学习曲线对于这个用例来说可能是彻底的过度杀伤力.

Tim*_*Tim 4

尽管您担心 Camel 对于这个用例来说可能是过度杀伤力,但我认为 ActiveMQ 对于您所描述的用例来说已经是严重过度杀伤力了。

您希望安排某件事在事件发生后 5 分钟发生,并且只消耗第一个事件并忽略第一个事件和 5 分钟结束之间的所有事件,对吗?为什么不通过ScheduledExecutorService或您最喜欢的调度机制将您的处理方法安排在 5 分钟后,并将事件保存在HashMap<User, Event>成员变量中。如果在处理方法触发之前该用户有更多事件进入,您只会看到已经存储了一个事件,而不存储新的事件,因此您将忽略除第一个之外的所有事件。在处理方法结束时,从您的 中删除该用户的事件HashMap,并且将存储和安排下一个进入的事件。

仅仅为了获得这种行为而运行 ActiveMQ 似乎超出了您的需要。或者如果不是,你能解释一下为什么吗?

编辑:

如果您确实走这条路,请不要使用消息 TTL 来使您的消息过期;只需让(唯一的)消费者将它们读入内存,并使用上述内存解决方案每 5 分钟仅处理(最多)一批。要么使用带有消息选择器的单个队列,要么使用动态队列(每个用户一个)。您不需要 DLQ 来实现延迟,即使您可以让它做到这一点,它也不会给您批处理所有内容的功能,因此您只能每 5 分钟运行一次。即使您知道如何走,这也不是您想要走的路。