我正在学习Spring Integration JMS。我遇到了一个问题,即我的主题不会持续等待客户尚未使用的待处理邮件。
基本上我启动ActiveMQ然后使用REST客户端我正在调用生产者发送消息50次,以便50个消息在主题中排队。在消费者端,我已经应用了5秒的睡眠定时器,以便每个消息以5秒的固定间隔消耗。然后介于两者之间我停止了ActiveMQ。同时,客户端消耗了一些消息,假设已经消耗了50个中的15个。然后,如果我重新启动ActiveMQ,我希望主题能够持续等待35条消息,但我无法在主题选项卡下的管理控制台中看到它。
这是我的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:int-jme="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
<!-- Component scan to find all Spring components -->
<context:component-scan base-package="com.geekcap.springintegrationexample" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="order" value="1" />
<property name="messageConverters">
<list>
<!-- Default converters -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</list>
</property>
</bean>
<!-- Define a channel to communicate out to a JMS Destination -->
<int:channel id="topicChannel"/>
<!-- Define the ActiveMQ connection factory -->
<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<!--
Define an adaptor that route topicChannel messages to the myTopic topic; the outbound-channel-adapter
automagically fines the configured connectionFactory bean (by naming convention
-->
<int-jms:outbound-channel-adapter channel="topicChannel"
destination-name="topic.myTopic"
pub-sub-domain="true" />
<!-- Create a channel for a listener that will consume messages-->
<int:channel id="listenerChannel" />
<int-jms:message-driven-channel-adapter id="messageDrivenAdapter"
channel="getPayloadChannel"
destination-name="topic.myTopic"
pub-sub-domain="true" />
<int:service-activator input-channel="listenerChannel" ref="messageListenerImpl" method="processMessage" />
<int:channel id="getPayloadChannel" />
<int:service-activator input-channel="getPayloadChannel" output-channel="listenerChannel" ref="retrievePayloadServiceImpl" method="getPayload" />
</beans>
我还读到默认模式是持久的。但就我而言,它似乎没有奏效。
修改
根据Gary Russel在添加属性后给出的答案
在<int-jms:message-driven-channel-adapter>
我面临与XML相关的问题
cvc-complex-type.3.2.2:不允许在'int-jms:message-driven-channel-adapter'元素中出现属性'subscription-durable'。
cvc-complex-type.3.2.2:不允许在'int-jms:message-driven-channel-adapter'元素中出现属性'durable-subscription-name'。
< / LI>请帮助
答案 0 :(得分:1)
默认情况下,这就是主题如何工作,读取JMS规范。
主题是发布/订阅;只有在场的订阅者才能收到该消息。
如果你发布5,启动消费者,发布另一个5;他只会得到第二个5。
如果你在获得全部5之前杀死经纪人;在重新启动期间,经纪人看到没有消费者,所以他清除了消息。
您可以通过使用持久订阅来更改此行为,在这种情况下,即使当前未连接,代理也会为每个此类订阅保留消息。
要使用Spring Integration进行配置,请在消息驱动的通道适配器上设置subscription-durable
,并为其指定唯一的subscription-name
。
答案 1 :(得分:0)
Activemq 中的主题不是持久和持久的,因此万一您的消费者之一宕机。你会丢失你的消息。
为了使主题持久和持久,您可以通过为每个消费者创建唯一的客户端 ID 来创建持久消费者。
但同样,如果您遵循微服务架构,这不是分布式的。因此,多个 Pod 或副本会在消费消息时产生问题,因为持久消费者不可能实现负载平衡。
为了缓解这种情况,Activemq 中有一个虚拟主题选项。下面提供了更多详细信息,
您可以在名为 VirtualTopic.MyTopic 的主题中通过您的制作人发送您的消息。 ** 注意:对于默认的 activemq 配置,您必须遵循此命名约定。但是是的,还有一种方法可以覆盖此命名约定。
现在,要通过多个消费者(此处为 A 和 B)使用您的消息,您还必须为您的消费者端目的地设置命名约定,例如。 Consumer.A.VirtualTopic.MyTopic Consumer.B.VirtualTopic.MyTopic 这两个消费者将通过上面创建的主题接收消息,并在相同的多个副本之间启用负载平衡消费者。
我希望这能帮助您解决有关 activemq 主题的问题。