如何在春季集成中为每个出站 jms 消息设置优先级?

Posted

技术标签:

【中文标题】如何在春季集成中为每个出站 jms 消息设置优先级?【英文标题】:How to set a priority per outbound jms message in spring integration? 【发布时间】:2016-01-17 15:13:18 【问题描述】:

嘿,所以我正在使用 spring 集成的 jms:outbound-channel-adapter 并且需要在将消息推送到消息传递系统之前设置消息的优先级。

现在在普通的 JMS 中,我有两种方法。

MessageProducer 上设置优先级:

this.producer.setPriority(i);

或者在发送方法本身:

channel.send(message, DeliveryMode.PERSISTENT, 5, 1000);

这些选项对我都不再可用,因为通道适配器将我从这些细节中抽象出来。

设置消息本身的优先级仅适用于 spring 集成的内存中channels,并且在我将其放入实际队列时立即失效。结果证明设置消息的优先级根本不是一个选项:JMS message priority not working on Message

通道适配器上有一个属性,我可以在其中设置优先级,但这是静态的。

    <jms:outbound-channel-adapter id="101Out" 
                              channel="101MessageChannel"
                              connection-factory="101Factory"
                              destination="QUEUE_NAME"
                              priority="1" />

我可以从属性文件中读取的最大值。 (或者我认为。我不确定)。我可以使用destination-expression 属性来检查传入的消息并将其动态路由到不同的目的地,但是没有priority-expression 对应部分可以让我对优先级执行相同的操作。

我有一些解决方法,但不是很好:

    <jms:outbound-channel-adapter id="101HighPriorityOut" 
                              channel="101HighPriorityChannel"
                              connection-factory="101Factory"
                              destination-expression="headers.QUEUE_NAME"
                              priority="1"
                              explicit-qos-enabled="true" />

    <jms:outbound-channel-adapter id="101LowPriorityOut" 
                              channel="101LowPriorityChannel"
                              connection-factory="101Factory"
                              destination-expression="headers.QUEUE_NAME"
                              priority="0"
                              explicit-qos-enabled="true" />

一旦确定需要什么优先级,我只需将消息路由到适当的出站适配器。但是,如果优先级的数量增加,我就会遇到麻烦。即使没有,拥有两个出站适配器而不是一个,因为我无法动态分配优先级,我认为这有点笨拙。

感谢帮助:-)

哦,我正在使用 Websphere MQ 作为我的消息代理。我不知道这是否与消息代理有关。

【问题讨论】:

【参考方案1】:

只需在消息中设置优先级标头...

<int:header-enricher ...>
    <int:priority value="2" />
</int:heaer-enricher>

适配器配置中的优先级是默认值,在没有优先级标头时使用(您可以使用属性占位符从属性文件中设置它)。

或者,使用表达式...

<int:header-enricher ...>
    <int:priority expression="payload.foo == 'bar' ? 1 : 2" />
</int:heaer-enricher>

<int:header-enricher ...>
    <int:priority expression="payload.priority" />
</int:heaer-enricher>

<int:header-enricher ...>
    <int:priority expression="@someBean.calculatePriority(payload)" />
</int:heaer-enricher>

【讨论】:

我仍然会进行静态查找,对吧?我现在有两个标头丰富器和一个通道适配器,而不是两个通道适配器。我有点需要一种从有效负载本身查找数据并将其分配给优先级的方法。没有它,我最终会为每个添加的新优先级编写额外的丰富器。 在标题丰富器中使用表达式:&lt;int:priority expression="payload.foo == 'bar' ? 1 : 2" /&gt; 太棒了。这完全简化了事情。非常感谢! 虽然这个答案是正确的,但自 spring-integration 4.1.0.RC1 以来这已经被打破(至少直到 5.2.3.RELEASE 并且取决于底层的 JMS 提供程序)参见github.com/spring-projects/spring-integration/issues/3179跨度>

以上是关于如何在春季集成中为每个出站 jms 消息设置优先级?的主要内容,如果未能解决你的问题,请参考以下文章

JMS 消息优先级不适用于 Message

Spring Integration DSL JMS 入站/出站网关

JMS学习四(ActiveMQ消息过滤)

在 java 1.7 中将 JMS 出站通道适配器转换为等效的 Spring Integration DSL

在 Spring Integration 中为消息设置生存时间

使用Spring集成组件关联2个JMS队列之间的消息