我正在尝试使用configure和测试ActiveMQ死信队列,但我有一些问题。正如官方文档所说:
当消息在Active MQ代理上过期时(它们超过了它们 生存时间,如果设置)或无法重新交付,他们被转移到 死信队列,所以他们可以被消费或浏览 管理员稍后。消息通常会重新传递给a 客户端在以下场景中:
- 客户正在使用交易 并在会话上调用rollback()。
- 客户正在使用交易 并在调用commit之前关闭。
- 客户正在使用 会话上的CLIENT_ACKNOWLEDGE并在该会话上调用recover()。
醇>
所以,我已经让我的Producer类在发送消息后创建事务会话和回滚事务。正如我所料,消息没有出现在目标队列中,但麻烦的是根本没有创建DLQ。我怎样才能管理死信队列?我无法使用JConsole找到它 - 只有目标队列,但不是DLQ。
你知道麻烦在哪里吗?有Producer.java和Spring配置!
<bean id="producer" class="com.jmsexamples.Producer">
<property name="connectionFactory" ref="jmsFactory" />
<property name="destination" ref="queue" />
<property name="login" value="roman" />
<property name="password" value="sawawluha" />
</bean>
<bean id="consumer" class="com.jmsexamples.Consumer">
<property name="connectionFactory" ref="jmsFactory" />
<property name="destination" ref="queue" />
<property name="login" value="roman" />
<property name="password" value="sawawluha" />
</bean>
<bean id="jdbc_ds" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/ActiveMQ?relaxAutoCommit=true" />
<property name="username" value="root" />
<property name="password" value="" />
<property name="poolPreparedStatements" value="true" />
</bean>
<amq:connectionFactory id="jmsFactory" brokerURL="tcp://localhost:6616" />
<amq:queue id="queue" physicalName="message.queue" />
<amq:broker id="msgBroker" persistent="true">
<amq:persistenceAdapter>
<amq:kahaDB directory="target/activemq-data/kahadb"
journalMaxFileLength="16mb" />
</amq:persistenceAdapter>
<amq:plugins>
<amq:loggingBrokerPlugin logAll="true" />
</amq:plugins>
<amq:destinationPolicy>
<amq:policyMap>
<amq:policyEntries>
<amq:policyEntry queue=">">
<amq:deadLetterStrategy>
<amq:individualDeadLetterStrategy
queuePrefix="DLQ." useQueueForQueueMessages="true"
processNonPersistent="true" />
</amq:deadLetterStrategy>
</amq:policyEntry>
</amq:policyEntries>
</amq:policyMap>
</amq:destinationPolicy>
<amq:transportConnectors>
<amq:transportConnector name="openwire"
uri="tcp://localhost:6616" />
</amq:transportConnectors>
</amq:broker>
制片:
public class Producer {
private String login;
private String password;
private ConnectionFactory connectionFactory;
private Destination destination;
public void setConnectionFactory(ConnectionFactory conFact) {
this.connectionFactory = conFact;
}
public void setDestination(Destination dest) {
this.destination = dest;
}
public void setLogin(String login) {
this.login = login;
}
public void setPassword(String password) {
this.password = password;
}
public void sendMessage(int count) {
Connection connection = null;
Session session = null;
try {
System.out.println("Loggining as " + login);
// it's not neccessary to set login and password in this example
// but when you are running a normal message server, you should use
// login and password for authentification
connection = connectionFactory.createConnection(this.login,
this.password); // estabilishing connection
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); // starting
// session
MessageProducer producer = session.createProducer(destination); // initializing
// of
// message
// producer
System.out.println("Client_acknowledge " + session.getTransacted());
for (int i = 0; i < count; i++) {
TextMessage message = session.createTextMessage();
message.setText("This is text message!");
producer.send(message);
System.out.println("message sent #" + i);
session.rollback();
}
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
session.commit();
session.close();
connection.close();
System.out.println("successfull");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
感谢您的帮助!
答案 0 :(得分:0)
从回滚的TX中的生产者发送的消息将不会被发送到死信队列。这些类型的消息被认为从未发布过,因此它们不是DLQ的候选者。由于您的客户已决定回滚TX这些消息,因此您的客户需要对其进行一些操作。
答案 1 :(得分:0)
从生产者方面 - 如果会话被回滚,则消息不会在DLQ中结束。
DLQ的目的是让出一条出路&#34;有问题的消息而不丢失任何数据。生产者应该知道要发送什么。如果回滚发送事务,则消息永远不会到达代理。交易消费者将确保一个&#34;毒药消息&#34;最终在DLQ上,所以它不会阻止进一步的传入消息。
在正常情况下,生产者的交易并没有真正做多。如果您想在给定时刻生成一组消息,您可以在交易中生成一个&#34;全部或全部&#34;行为。