消费过程发生错误容易造成死循环

1.控制重发次数
2.try+catch+手动ack
3.try+catch+手动ack+死信队列(重试次数就失效了,因为捕捉确认后被打入了相应的死信队列)

void basicAck(long deliveryTag, boolean multiple) throws IOException;
第一个参数deliveryTag:发布的每一条消息都会获得一个唯一的deliveryTag,(任何channel上发布的第一条消息的deliveryTag为1,此后的每一条消息都会加1),deliveryTag在channel范围内是唯一的
第二个参数multiple:批量确认标志。如果值为true,则执行批量确认,此deliveryTag之前收到的消息全部进行确认; 如果值为false,则只对当前收到的消息进行确认

void basicReject(long deliveryTag, boolean requeue) throws IOException;
第一个参数deliveryTag:发布的每一条消息都会获得一个唯一的deliveryTag,deliveryTag在channel范围内是唯一的
第二个参数requeue:表示如何处理这条消息,如果值为true,则重新放入RabbitMQ的发送队列,如果值为false,则通知RabbitMQ销毁这条消息

channel.basicNack是 channel.basicReject的补充,提供一次对多条消息进行拒绝的功能
void basicNack(long deliveryTag, boolean multiple, boolean requeue) throws IOException; 
第一个参数deliveryTag:发布的每一条消息都会获得一个唯一的deliveryTag,deliveryTag在channel范围内是唯一的
第二个参数multiple:批量确认标志。如果值为true,包含本条消息在内的、所有比该消息deliveryTag值小的 消息都被拒绝了(除了已经被 ack 的以外);如果值为false,只拒绝三本条消息
第三个参数requeue:表示如何处理这条消息,如果值为true,则重新放入RabbitMQ的发送队列,如果值为false,则通知RabbitMQ销毁这条消息

 // 每个客户端每次最后获取N个消息
channel.basicQos(1);


 




 * (Wmxg)表控制层
*
* @author makejava
* @since 2021-03-27 23:02:34 结合producetransation 看文档的图片理解
*/
@Component
public class OrderMqConsumer {
/**
* 服务对象
*/
private int count=1;
@Autowired
private DispatcherService dispatcherService;

@RabbitHandler
// @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "order.fanout.exchange",
// durable = "true",autoDelete = "false"),
// exchange = @Exchange(value = "order_fanout_exchange",type = ExchangeTypes.FANOUT)))
@RabbitListener(queues ="order.fanout.exchange")
public void messageconsumer(String mesg, Channel channel, CorrelationData correlationData, @Header(AmqpHeaders.DELIVERY_TAG)long tag) throws IOException {
try {
//1收到消息是
System.out.println("收到的消息是:" + mesg + ",count=" + count);
//2获取订单的信息
Kung kung = JSON.parseObject(mesg, Kung.class);
//3获取ID
String orderId = kung.getOrderId();
String userId = kung.getUserId();
//4保存运单
Wmxg wmxg = new Wmxg();
wmxg.setOrderId(orderId);
wmxg.setUserId(userId);
          //幂等性的问题,存在则更新,不存在则插入   使用分布式锁也可以解决    避免重试时重复派单
dispatcherService.insert(wmxg);
System.out.println(1 / 0);

//对当前消息进行应答
//用catch进行捕捉
channel.basicAck(tag,false); //只对当前收到的消息进行确认
true对消息进行批量确认

} catch (Exception e) {
//如果出现异常的情况,根据实际情况去进行重发
//重发一次后,丢失还是日记,库存根据自己的业务场景去定
//参数1:消息的tag
// 参数2:false 多条处理
// 参数3:requeue重发 fasle 不会重发,会把消息打入死信队列(自己建立一个死信队列,如下文书所示) true会进入死循环的重发(造成重复消费),建议true的情况下,不使用try catch 否则造成循环
channel.basicNack(tag,false,false);

}
}

自己建立的死信队列:
@Bean
public Queue orderQueue() {
Map<String,Object> args=new HashMap<>();
args.put("x-message-ttl",5000);//这里过期时间一定是一个INT类型
args.put("x-dead-letter-exchange","dead_direct_exchange");//绑定死信队列交换机
args.put("x-max-length",5);//指定最大接受多少条
args.put("x-dead-letter-routing-key","dead");//fanout没有key
return new Queue("order.fanout.exchange", true,false,false,args);
}
 
 
 
 

rabbitMq消费死循环的更多相关文章

  1. C#多线程技术提高RabbitMQ消费吞吐率

    一.课程介绍 本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的第二部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高级编程的技巧分享出来给大家进行学习,不断的收集.整理 ...

  2. 提升RabbitMQ消费速度的一些实践

    RabbitMQ是一个开源的消息中间件,自带管理界面友好.开发语言支持广泛.没有对其它中间件的依赖,而且社区非常活跃,特别适合中小型企业拿来就用.这篇文章主要探讨提升RabbitMQ消费速度的一些方法 ...

  3. 由一个RABBITMQ监听器死循环引出的SPRING中BEAN和MAPPER接口的注入问题

    1 @Slf4j 2 @RestController 3 @Component 4 public class VouchersReceiverController implements Message ...

  4. RabbitMQ 消费消息

    1, 创建一个 springboot 项目, 导入依赖(和生产者一致) 2, application.properties (基础配置和生产者一致, 消费者需要再额外配置一些) # rabbitmq ...

  5. rabbitmq消费端加入精确控频。

    控制频率之前用的是线程池的数量来控制,很难控制.因为做一键事情,做一万次,并不是每次消耗的时间都相同,所以很难推测出到底多少线程并发才刚好不超过指定的频率. 现在在框架中加入控频功能,即使开200线程 ...

  6. rabbitmq 生产者 消费者(多个线程消费同一个队列里面的任务。) 一个通用rabbitmq消费确认,快速并发运行的框架。

    rabbitmq作为消息队列可以有消息消费确认机制,之前写个基于redis的通用生产者 消费者 并发框架,redis的list结构可以简单充当消息队列,但不具备消费确认机制,随意关停程序,会丢失一部分 ...

  7. RabbitMQ消费方式汇总

    在学习本章节前,请先学习之前的章节:Java访问RabbitMQ:https://www.cnblogs.com/duanjt/p/10057330.htmlRabbitMQ消息发布时的权衡:http ...

  8. RabbitMQ消费端消息的获取方式(.Net Core)

    1[短链接]:BasicGet(String queue, Boolean autoAck) 通过request的方式独自去获取消息,断开式,一次次获取,如果返回null,则说明队列中没有消息. 隐患 ...

  9. Rabbitmq消费失败死信队列

    Rabbitmq 重消费处理 一 处理流程图: 业务交换机:正常接收发送者,发送过来的消息,交换机类型topic AE交换机: 当业务交换机无法根据指定的routingkey去路由到队列的时候,会全部 ...

随机推荐

  1. Oracle19c 如何用rman duplicate 克隆一个数据库。(Backup-Based, achive log)

    Oracle19c 如何用rman duplicate 克隆一个数据库.(Backup-Based, achive log) 首先克隆有两种方法,一种是Backup-Based,一种是Active方式 ...

  2. 注解@ConfigurationProperties使用方法(二十)

    前言 最近在思考使用java config的方式进行配置,java config是指基于java配置的spring.传统的Spring一般都是基本xml配置的,后来spring3.0新增了许多java ...

  3. 《手把手教你》系列技巧篇(十一)-java+ selenium自动化测试-元素定位大法之By tag name(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...

  4. mysql采坑笔记

    mysqld --initialize-insecure // 初始化数据 mysql -u root -p // 登录 navicat for mysql 1251错误解决方法 ALTER USER ...

  5. 大数据学习(10)—— Hive进阶

    前面提到了Hive的知识点非常零散,我不知道该怎么把这些知识点分类,跟SQL关系没那么大的就放在这一篇吧. Hive Serde 参考Hive Serde Serde是啥 Serde是序列化和反序列化 ...

  6. 自学linux——4.Linux的自有服务(基础篇)

    linux自有服务(内置) 一.运行级别(模式) 在Linux中存在一个进程:init,进程id是1. 查看进程:#ps -ef|grep init 对应的配置文件:inittab(运行级别配置文件位 ...

  7. OpenGL学习笔记(五)变换

    目录 变换 向量 向量的运算 向量与标量运算 向量取反 向量加减 求向量长度 向量的单位化 向量相乘 点乘(Dot Product) 叉乘 矩阵 矩阵的加减 矩阵的数乘 矩阵相乘 矩阵与向量相乘 与单 ...

  8. Mybatis学习笔记-日志

    日志工厂 如果一个数据库操作出现异常,在排错时,则需要日志 SLF4J Apache Commons Logging(COMMONS_LOGGING) LOG4J LOG4J2 JDK logging ...

  9. TypeScript学习笔记(三)泛型、模块化和命名空间

    目录 一.泛型 1. 泛型函数 2. 泛型类 3. 泛型接口 写法一 写法二 两种写法的区别 二.模块化 1. export写法一 2. export写法二 3. 为引入的方法或变量起别名 4. ex ...

  10. Mol Cell丨吕志民团队揭示琥珀酰化介导的肿瘤细胞氧化应激调控新机制

    蛋白质琥珀酰化修饰 (succinylation) ,作为赖氨酸酰化修饰家族的重要一员,于2011年由芝加哥大学赵英明教授团队在Nature Chemical Biology 发文被首次报道,并被评为 ...