CLIENT_ACKNOWLEDGE机制测试

本文主要探讨了在Spring框架下使用ActiveMQ CLIENT_ACKNOWLEDGE模式时遇到的问题。测试发现,即使在onMessage方法中未手动acknowledge消息,框架也会在方法执行结束时自动ack。而在原生API中,未调用session.recover()和message.acknowledge()会导致消息不被确认,但不会立即重发,只有在session与broker断开后,消息才会重发并可能进入DLQ队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring框架测试

spring配置

<bean id="queueListenerContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="destination" ref="demoQueueDestination" />
    <property name="messageListener" ref="queueMessageListener" />
    <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE"/>
 </bean>

测试代码

public class QueueMessageListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        TextMessage textmessage = (TextMessage)message;
        try {
            System.out.println("接收到消息::"+ textmessage.getText());
            System.out.println("接消息完毕!");
            int i = 1/0;  //人工异常
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

测试结果
这里写图片描述
ActiveMQ.Demo对列的MessagesEnqueued对列在生产者一发送消息时便变成15,且onMessage方法已接收到了消息,但MessagesDequeued一直是14,此条消息会重复接收6次,之后MessagesDequeued变成15,并且ActiveMQ.DLQ队列消息数加1。
⚠️与AUTO_ACKNOWLEDGE机制一样。
若没有int i = 1/0;也不调用message.acknowledge()
⚠️onMessage方法执行结束时,框架会自动调用message.acknowledge()

原生api

 public static void main(String[] args) throws Exception {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER
                , ActiveMQConnection.DEFAULT_PASSWORD
                , ActiveMQConnection.DEFAULT_BROKER_URL);
        conn = connectionFactory.createConnection();
        // 事务性会话,自动确认消息
        session = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
        // 消息的目的地(Queue/Topic)
        destination = session.createQueue(SUBJECT);
        // destination = session.createTopic(SUBJECT);
        // 消息的提供者(生产者)
        consumer = session.createConsumer(destination);
        conn.start();
        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                TextMessage textmessage = (TextMessage)message;
                try {
                    System.out.println("接收到消息::"+ textmessage.getText());
                    System.out.println("接消息完毕!");
                } catch (JMSException e) {
                }
                try {
                    session.recover();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }

当没有调用session.recover()和message.acknowledge()方法时,
这里写图片描述
ActiveMQ.Demo对列的MessagesEnqueued队列在生产者一发送消息时加1,MessagesDequeued不会增加,意味着并没有从对列中删除,消息没有被ack。
⚠️此时,消息并不会重发,若当前session与broker断开连接,此消息会重发给新连接的session。
当调用session.recover()方法时,没有被确认的消息会被重发六次
这里写图片描述
之后从ActiveMQ.Demo队列中删除,并被丢到ActiveMQ.DLQ队列中。

import requests import sseclient import json import time from datetime import datetime import logging # 配置日志记录器,将日志输出到group_log.log文件 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') def assistant_service(query: str, citics_cus_app_id: str): data = { 'messages': [], 'question_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 'message_id': 1, 'question': [{'type': 'text', 'value': query}], 'web_search_flag': False, 'session_id': '', 'app_id': citics_cus_app_id, "stream":False } url = 'http://ai-api.citicsinfo.com/assistant/chat' headers = { 'API-KEY': 'CAP_ass1stanT', } response = requests.post(url, json=data, headers=headers, stream=False) return response.json() def agent_callback(message): agent_id = message['agent_id'] query = message['query'] resp = assistant_service(query=query, citics_cus_app_id=agent_id) return resp['answer'][0]['total_answer'] def receive_message(): msg = agent_consumer.receive() message_data = msg.data().decode('utf-8') message = json.loads(message_data) content = agent_callback(message) agent_consumer.acknowledge(msg) logging.info(content) return message_data if __name__=='__main__': from db.client import pulsar_client from pulsar import ConsumerType agent_consumer = pulsar_client.subscribe(topic='iops/cap/wework_group_agent', subscription_name='fundop-subsrcibe-shared', consumer_type=ConsumerType.Shared) while True: message_data = receive_message() time.sleep(0.5) 将这个代码改写成异步任务
最新发布
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值