簡體   English   中英

無法讓ActiveMQ重新發送我的消息

[英]Can't get ActiveMQ to resend my messages

我有一個用Java編寫的單線程ActiveMQ使用者。 我要做的就是從隊列中接收()一個消息,嘗試將其發送到Web服務,如果成功則確認()它。 如果Web服務調用失敗,我希望消息保留在隊列中並在超時后重新發送。

除了重新發送部分之外,它或多或少都在工作:每次重新啟動我的消費者時,它會為仍然在隊列中的每個消息收到一條消息,但是在發送它們之后,消息永遠不會被重新發送。

我的代碼看起來像:

public boolean init() throws JMSException, FileNotFoundException, IOException {
    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
    RedeliveryPolicy policy = new RedeliveryPolicy();
    policy.setInitialRedeliveryDelay(500);
    policy.setBackOffMultiplier(2);
    policy.setUseExponentialBackOff(true);

    connectionFactory.setRedeliveryPolicy(policy);
    connectionFactory.setUseRetroactiveConsumer(true); // ????
    Connection connection = connectionFactory.createConnection();

    connection.setExceptionListener(this);
    connection.start();

    session = connection.createSession(transacted, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
    destination = session.createQueue(subject); //???

    consumer = session.createConsumer(destination);
    //consumer.setMessageListener(this); // message listener had same behaviour

}

private void process() {
    while(true) {
        System.out.println("Waiting...");
        try {
            Message message = consumer.receive();
            onMessage(message);
        } catch (JMSException e) {
            e.printStackTrace();
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onMessage(Message message) {
    System.out.println("onMessage");
    messagesReceived++;

    if (message instanceof TextMessage) {
        try {
            TextMessage txtMsg = (TextMessage) message;
            String msg = txtMsg.getText();

            if(!client.sendMessage(msg)) {
                System.out.println("Webservice call failed. Keeping message");
                //message.
            } else {
                message.acknowledge();
            }

            if (transacted) {
                if ((messagesReceived % batch) == 0) {
                    System.out.println("Commiting transaction for last " + batch + " messages; messages so far = " + messagesReceived);
                    session.commit();
                }
            }
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

我目前沒有使用交易(也許我應該這樣做?)。

我確定我錯過了一些簡單的東西,很快就會拍打我的額頭,但我似乎無法弄清楚這是怎么回事。 謝謝!


編輯:由於代表不夠,我自己無法回答:

好的,經過一些實驗,事實證明交易是實現這一目標的唯一方法。 這是新代碼:

public boolean init() throws JMSException, FileNotFoundException, IOException {
    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
    RedeliveryPolicy policy = new RedeliveryPolicy();
    policy.setInitialRedeliveryDelay(1000L);
    policy.setMaximumRedeliveries(RedeliveryPolicy.NO_MAXIMUM_REDELIVERIES);

    connectionFactory.setRedeliveryPolicy(policy);
    connectionFactory.setUseRetroactiveConsumer(true);
    Connection connection = connectionFactory.createConnection();

    connection.setExceptionListener(this);
    connection.start();

    session = connection.createSession(transacted, ActiveMQSession.CLIENT_ACKNOWLEDGE);
    destination = session.createQueue(subject);

    consumer = session.createConsumer(destination);
}

@Override
public void onMessage(Message message) {
    System.out.println("onMessage");
    messagesReceived++;

    if (message instanceof TextMessage) {
        try {
            TextMessage txtMsg = (TextMessage) message;
            String msg = txtMsg.getText();

            if(client.sendMessage(msg)) {
                if(transacted) {
                    System.out.println("Call succeeded - committing message");
                    session.commit();
                }
                //message.acknowledge();
            } else {
                if(transacted) {
                    System.out.println("Webservice call failed. Rolling back message");
                    session.rollback();
                }
            }

        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

現在,按照“重新傳遞策略”中的指定,每1000毫秒重新發送一條消息。

希望這有助於其他人! :)

您不必使用事務,CLIENT_ACK / Session.recover()也可以使用...

發生以下任何情況時,會將郵件重新傳遞給客戶端:

  • 使用事務會話並調用rollback()。
  • 在調用commit之前關閉事務會話。
  • 會話正在使用CLIENT_ACKNOWLEDGE並調用Session.recover()。

請參閱http://activemq.apache.org/message-redelivery-and-dlq-handling.html

暫無
暫無

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

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