springboot-rabbitmq ack的问题?

如何手动ack

- 网上的方式1:实现channelAwareMessageListener

	
	public class RabbitMsgReceiver implements ChannelAwareMessageListener{
	
	public void onMessage(Message message, Channel channel) throw Exception{
		System.out.println(JSON.toJSONString(message));
		//解决basicAck 首先设置basicAck 为false
		channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
		System.out.println("onMessage=" + new String(message.getBody()));
}
}
	

- 存在的问题:最近有个需求是使用消息转换器直接传输java对象

监听器的代理对象这样写的

	public class OrderHandler {
    
    public void handleMessage(Order order){
        System.out.println("===order======= " + "[id=" + order.getId() + "name=" + order.getName()
                + "content=" + order.getContent() + "]");
        //告诉服务器收到这条消息 已经被我消费了 可以在队列删掉 这样以后就不会再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
    }
}

//监听容器的代码大致如下

 @Bean
    SimpleMessageListenerContainer container(ConnectionFactory conn) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(conn);
        container.setQueueNames(EMAIL_QUEUE);//监听的队列
        container.setConcurrentConsumers(1); //当前的消费者数量
        container.setMaxConcurrentConsumers(5); //  最大的消费者数量
        container.setDefaultRequeueRejected(true); //是否重回队列
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //签收模式
        container.setExposeListenerChannel(true);


        //适配器方式添加监听器
        //MessageListenerAdapter adapter = new MessageListenerAdapter(new EmailMessageDelegate());
        //adapter.setDefaultListenerMethod("consumeMessage");
        //adapter.setMessageConverter(new Jackson2JsonMessageConverter());
        /**--------支持java对象转换-------------------------------
        Jackson2JsonMessageConverter jacksonConverter = new Jackson2JsonMessageConverter();
        DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
        javaTypeMapper.setTrustedPackages("*");
        jacksonConverter.setJavaTypeMapper(javaTypeMapper);
        adapter.setMessageConverter(jacksonConverter);
        container.setMessageListener(adapter);
        return container;
         */
        Jackson2JsonMessageConverter jacksonConverter = new Jackson2JsonMessageConverter();
        DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
        javaTypeMapper.setTrustedPackages("*");
        Map<String, Class<?>> idClassMapping = new HashMap<>();
        //idClassMapping.put("emailModel", EmailModel.class);
        idClassMapping.put("order", Order.class);
        javaTypeMapper.setIdClassMapping(idClassMapping);

        jacksonConverter.setJavaTypeMapper(javaTypeMapper);
        MessageListenerAdapter orderAdapter = new MessageListenerAdapter(new OrderHandler());
        orderAdapter.setMessageConverter(jacksonConverter);
        container.setMessageListener(orderAdapter);
        return container;
    }

发现在生产数据的时候会重复消费,不清楚在哪里怎么设置手动ack,知道的大佬,能不能告诉下小弟,不胜感激

### Spring Boot 中 RabbitMQ 的消息确认 (ACK) 机制 #### 配置 `application.yml` 文件中的 RabbitMQ 参数 为了启用消息的手动确认模式,在 `application.yml` 或 `application.properties` 文件中需指定相应的配置项。具体来说,通过设置 `acknowledge-mode: manual` 来开启消费端的手动应答功能[^4]。 ```yaml spring: rabbitmq: listener: simple: acknowledge-mode: manual # 设置为手动确认方式 ``` #### 创建监听器类并处理接收到的消息 当应用程序作为消费者接收到来自 RabbitMQ 的消息时,可以通过实现 `ChannelAwareMessageListener` 接口来定义具体的业务逻辑以及执行 ACK 操作的方法。下面是一个简单的例子: ```java import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener; import com.rabbitmq.client.Channel; public class MyMessageListener implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { try { String msg = new String(message.getBody()); System.out.println("Received message: " + msg); // 处理业务逻辑 // 手动确认消息已被成功处理 channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); } catch (Exception e) { // 如果发生异常,则拒绝该条消息,并决定是否重新入队 channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true); } } } ``` 在此代码片段中,每当有新消息到达时都会触发 `onMessage()` 方法;如果一切正常则调用 `basicAck()` 进行确认,反之则会调用 `basicNack()` 表明存在问题[^2]。 #### 发送测试消息验证效果 最后一步是在控制器或其他地方编写发送消息的功能以便于测试整个流程。可以创建一个 RESTful API 端点用于向队列推送数据,例如: ```java @RestController @RequestMapping("/send") public class MessageController { private final AmqpTemplate amqpTemplate; @Autowired public MessageController(AmqpTemplate amqpTemplate){ this.amqpTemplate = amqpTemplate; } @GetMapping public ResponseEntity<String> sendMessage(@RequestParam String message){ amqpTemplate.convertAndSend("exchangeName", "routingKey", message); return ResponseEntity.ok("Sent"); } } ``` 此时启动应用并通过浏览器或 Postman 访问 `/send?message=HelloRabbitMQ` 即可完成一次完整的交互过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值