簡體   English   中英

未創建ActiveMQ死信隊列

[英]ActiveMQ Dead Letter Queue isn't created

我正在嘗試使用configure和測試ActiveMQ死信隊列,但我有一些問題。 正如官方文件所說:

當消息在Active MQ代理上過期(它們超過它們的生存時間,如果設置)或無法重新傳遞時,它們將被移動到死信隊列,因此它們可以被消耗或瀏覽管理員稍后。 在以下情況下,通常會將消息重新傳遞給客戶端:

  1. 客戶端正在使用事務並在會話上調用rollback()。
  2. 客戶端正在使用事務並在調用commit之前關閉。
  3. 客戶端在會話上使用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();
            }

        }
    }
}

謝謝你的幫助!

從回滾的TX中的生產者發送的消息將不會被發送到死信隊列。 這些類型的消息被認為從未發布過,因此它們不是DLQ的候選者。 由於您的客戶已決定回滾TX這些消息,因此您的客戶需要對其進行一些操作。

從生產者方面 - 如果會話被回滾,消息將不會在DLQ中結束。

DLQ的目的是在沒有丟失任何數據的情況下對有問題的消息進行“解決”。 生產者應該知道要發送什么。 如果回滾發送事務,則消息永遠不會到達代理。 事務性消費者將確保DLQ上的“有害消息”結束,因此它不會阻止進一步的傳入消息。

在正常情況下,生產者的事務並沒有真正起作用。 如果要在給定時刻生成一組消息,則可以在事務中生成“全部或全部”行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM