Golang实现RabbitMQ中死信队列各个情况
下面这段教程针对是你已经有一些基本的MQ的知识,比如说能够很清楚的理解queue、exchange等概念,如果你还不是很理解,我建议你先访问官网查看基本的教程。
文章目录
- 1、造成死信队列的主要原因
- 2、操作逻辑图
- 3、代码实战
- 3.1 针对原因1:消费者超出时间未应答
- 3.3 针对原因2:限制一定的长度
- 3.3 针对原因3:消费者拒绝的消息回到死信队列中
1、造成死信队列的主要原因
- 消费者超时未应答
- 队列的容量有限
- 消费者拒绝了的消息
2、操作逻辑图
3、代码实战
其实整体的思路就是分别创建一个normal_exchange、dead_exchange、normal_queue、dead_queue,然后将normal_exchange与normal_queue进行绑定,将dead_exchange与dead_queue进行绑定,这里比较关键的一个点在于说如何将normal_queue与dead_exchange进行绑定,这样才能将错误的消息传递过来。下面就是这段代码的关键。
// 声明一个normal队列_, err = ch.QueueDeclare(constant.NormalQueue,true,false,false,false,amqp.Table{//"x-message-ttl": 5000, // 指定过期时间//"x-max-length": 6, // 指定长度。超过这个长度的消息会发送到dead_exchange中"x-dead-letter-exchange": constant.DeadExchange, // 指定死信交换机"x-dead-letter-routing-key": constant.DeadRoutingKey, // 指定死信routing-key})
3.1 针对原因1:消费者超出时间未应答
consumer1.go
package day07import (amqp "github.com/rabbitmq/amqp091-go""log""v1/utils"
)type Constant struct {NormalExchange stringDeadExchange stringNormalQueue stringDeadQueue stringNormalRoutingKey stringDeadRoutingKey string
}func Consumer1() {// 获取连接ch := utils.GetChannel()// 创建一个变量常量constant := Constant{NormalExchange: "normal_exchange",DeadExchange: "dead_exchange",NormalQueue: "normal_queue",DeadQueue: "dead_queue",NormalRoutingKey: "normal_key",DeadRoutingKey: "dead_key",}// 声明normal交换机err := ch.ExchangeDeclare(constant.NormalExchange,amqp.ExchangeDirect,true,false,false,false,nil,)utils.FailOnError(err, "Failed to declare a normal exchange")// 声明一个dead交换机err = ch.ExchangeDeclare(constant.DeadExchange,amqp.ExchangeDirect,true,false,false,false,nil,)utils.FailOnError(err, "Failed to declare a dead exchange")// 声明一个normal队列_, err = ch.QueueDeclare(constant.NormalQueue,true,false,false,false,amqp.Table{"x-message-ttl": 5000, // 指定过期时间//"x-max-length": 6,"x-dead-letter-exchange": constant.DeadExchange, // 指定死信交换机"x-dead-letter-routing-key": constant.DeadRoutingKey, // 指定死信routing-key})utils.FailOnError(err, "Failed to declare a normal queue")// 声明一个dead队列:注意不要给死信队列设置消息时间,否者死信队列里面的信息会再次过期_, err = ch.QueueDeclare(constant.DeadQueue,true,false,false,false,nil)utils.FailOnError(err, "Failed to declare a dead queue")// 将normal_exchange与normal_queue进行绑定err = ch.QueueBind(constant.NormalQueue, constant.NormalRoutingKey, constant.NormalExchange, false, nil)utils.FailOnError(err, "Failed to binding normal_exchange with normal_queue")// 将dead_exchange与dead_queue进行绑定err = ch.QueueBind(constant.DeadQueue, constant.DeadRoutingKey, constant.DeadExchange, false, nil)utils.FailOnError(err, "Failed to binding dead_exchange with dead_queue")// 消费消息msgs, err := ch.Consume(constant.NormalQueue,"",false, // 这个地方一定要关闭自动应答false,false,false,nil)utils.FailOnError(err, "Failed to consume in Consumer1")var forever chan struct{}go func() {for d := range msgs {if err := d.Reject(false); err != nil {utils.FailOnError(err, "Failed to Reject a message")}}}()log.Printf(" [*] Waiting for logs. To exit press CTRL+C")<-forever
}
consumer2.go
package day07import (amqp "github.com/rabbitmq/amqp091-go""log""v1/utils"
)func Consumer2() {// 拿取信道ch := utils.GetChannel()// 声明一个交换机err := ch.ExchangeDeclare("dead_exchange",amqp.ExchangeDirect,true,false,false,false,nil)utils.FailOnError(err, "Failed to Declare a exchange")// 接收消息的应答msgs, err := ch.Consume("dead_queue","",false,false,false,false,nil,)var forever chan struct{}go func() {for d := range msgs {log.Printf("[x] %s", d.Body)// 开启手动应答ßd.Ack(false)}}()log.Printf(" [*] Waiting for logs. To exit press CTRL+C")<-forever}
produce.go
package day07import ("context"amqp "github.com/rabbitmq/amqp091-go""strconv""time""v1/utils"
)func Produce() {// 获取信道ch := utils.GetChannel()// 声明一个交换机err := ch.ExchangeDeclare("normal_exchange",amqp.ExchangeDirect,true,false,false,false,nil)utils.FailOnError(err, "Failed to declare a exchange")ctx, cancer := context.WithTimeout(context.Background(), 5*time.Second)defer cancer()// 发送了10条消息for i := 0; i < 10; i++ {msg := "Info:" + strconv.Itoa(i)ch.PublishWithContext(ctx,"normal_exchange","normal_key",false,false,amqp.Publishing{ContentType: "text/plain",Body: []byte(msg),})}
}
3.3 针对原因2:限制一定的长度
只需要改变consumer1.go中的对normal_queue的声明
// 声明一个normal队列_, err = ch.QueueDeclare(constant.NormalQueue,true,false,false,false,amqp.Table{//"x-message-ttl": 5000, // 指定过期时间"x-max-length": 6,"x-dead-letter-exchange": constant.DeadExchange, // 指定死信交换机"x-dead-letter-routing-key": constant.DeadRoutingKey, // 指定死信routing-key})
3.3 针对原因3:消费者拒绝的消息回到死信队列中
这里需要完成两点工作
工作1:需要在consumer1中作出拒绝的操作
go func() {for d := range msgs {if err := d.Reject(false); err != nil {utils.FailOnError(err, "Failed to Reject a message")}}}()
工作2:如果你consume的时候开启了自动应答一定要关闭
// 消费消息msgs, err := ch.Consume(constant.NormalQueue,"",false, // 这个地方一定要关闭自动应答false,false,false,nil)
其他的部分不需要改变,按照问题1中的设计即可。
相关文章:
Golang实现RabbitMQ中死信队列各个情况
下面这段教程针对是你已经有一些基本的MQ的知识,比如说能够很清楚的理解queue、exchange等概念,如果你还不是很理解,我建议你先访问官网查看基本的教程。 文章目录1、造成死信队列的主要原因2、操作逻辑图3、代码实战3.1 针对原因1࿱…...
react源码分析:组件的创建和更新
这一章节就来讲讲ReactDOM.render()方法的内部实现与流程吧。 因为初始化的源码文件部分所涵盖的内容很多,包括创建渲染、更新渲染、Fiber树的创建与diff,element的创建与插入,还包括一些优化算法,所以我就整个的React执行流程画了…...
Android Lmkd 低内存终止守护程序
一、低内存终止守护程序 Android 低内存终止守护程序 (lmkd) 进程可监控运行中的 Android 系统的内存状态,并通过终止最不必要的进程来应对内存压力大的问题,使系统以可接受的性能水平运行。 所有应用进程都是从zygote孵化出来的,记录在AMS…...
快速掌握 Flutter 图片开发核心技能
大家好,我是 17。 在 Flutter 中使用图片是最基础能力之一。17 做了精心准备,满满的都是干货!本文介绍如何在 Flutter 中使用图片,尽量详细,示例完整,包会! 使用网络图片 使用网络图片超级简…...
复习使用git(二)
删除远程分支 git push origin --delete 分支名 撤销修改 撤销工作区的修改 已修改,但尚未添加(add),使用 git restore 文件名 撤销工作区的修改。 Note: “git checkout – 文件名”,checkout 检出的意思&#x…...
魔兽世界335服务端架设对外网开放的步骤
警告:在没有网络安全防护措施或基础知识的情况下,开放端口可能造成被黑客入侵、流量攻击、破坏数据、资料泄露等情况的发生。在你选择开放端口时,视为已经充分了解可能发生的后果、危害,清楚自己在做什么,并且自己将对…...
华为OD机试模拟题 用 C++ 实现 - 通信误码(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明通信误码题目输入输出示例一输入输出说明示例二输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,...
Vue 核心
文章目录Vue 核心一,Vue 简介(一)官网(二)介绍与描述(三)Vue 的特点(四)与其它 JS 框架的关联(五)Vue 周边库二,初识 Vue三࿰…...
Kylin V10桌面版arm3568 源码安装redis
上传redis-5.0.14.tar.gz到/home/kylin/下载;解压kylinkylin:~/下载$ tar -zxvf redis-5.0.14.tar.gz/opt下新建redis目录,并将上面解压的文件夹移到此处kylinkylin:~/下载$ sudo mv redis-5.0.14 /opt/redis/编译:kylinkylin:/opt/redis/red…...
【ICCV2022】 CAPAO:一种高效的单阶段人体姿态估计模型
CAPAO:一种高效的单阶段人体姿态估计模型 重新思考关键点表示:将关键点和姿态建模作为多人姿态估计的对象(Rethinking Keypoint Representations: Modeling Keypoints and Poses as Objects for Multi-Person Human Pose Estimation…...
ROS1学习笔记:ROS中的坐标管理系统(ubuntu20.04)
参考B站古月居ROS入门21讲:ROS中的坐标系管理系统 基于VMware Ubuntu 20.04 Noetic版本的环境 文章目录一、机器人中的坐标变换二、TF功能包三、小海龟跟随实验3.1 启动实验3.2 查看当前的TF树3.3 坐标相对位置可视化3.3.1 tf_echo3.3.2 rviz一、机器人中的坐标变换…...
requests---(2)session简介与自动写博客
目录:导读 session简介 session登录 自动写博客 获取登录cookies 抓取写博客接口 requests自动写博客 写在最后 http协议是无状态的,也就是每个请求都是独立的。那么登录后的一系列动作,都需要用cookie来验证身份是否是登录状态&#…...
基于 HAProxy + Keepalived 搭建 RabbitMQ 高可用集群
RabbitMQ 集群 通常情况下,在集群中我们把每一个服务称之为一个节点,在 RabbitMQ 集群中,节点类型可以分为两种: 内存节点:元数据存放于内存中。为了重启后能同步数据,内存节点会将磁盘节点的地址存放于磁…...
基于51单片机和proteus的智能调速风扇设计
此智能风扇是基于51单片机和proteus的仿真设计,功能如下: 1. Timer0 PWM控制电机转速 2. DHT11采集温湿度 3. LCD1602显示温湿度及电机状态 4. 按键控制电机加减速启停等 5. 串口控制电机加减速启停等 功能框图如下: Proteus仿真界面如下…...
SQL Server开启CDC的完整操作过程
这里写自定义目录标题写在前面SQL Server开启CDC1. 将指定库的实例先开启CDC2. 开启需要开启CDC的表3. 关闭CDC功能更详细信息参照官网写在前面 鉴于老旧数据的结构和项目都在sqlserver上存储,且迁移成本巨大,当下要为sqlserver的存储过程减负。要将一部…...
【Spring Cloud Alibaba】008-Sentinel
【Spring Cloud Alibaba】008-Sentinel 文章目录【Spring Cloud Alibaba】008-Sentinel一、服务雪崩1、概述2、解决方案常见的容错机制二、Sentinel:分布式系统的流量防卫兵1、**Sentinel** 概述简介特性Sentinel 的开源生态Sentinel 的历史2、Sentinel 基本概念资源…...
解读CRC校验计算
个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 参考:http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html 参考:https://en.wikipedia.org/wiki/Cyclic_redundancy_check 参考:https://www.cnblogs.com/…...
深入理解Spring MVC下
上一篇博客从理论概念上来梳理Spring MVC相关知识,此篇博客将通过spring官网提供showcase代码为例子,详细介绍showcase代码中包含的各个例子是如何实现的。官网的showcase代码包含的主要例子包括,Demo地址:Mapping Requests&#…...
【Linux】ssh-keygen不需要回车,自动生成密钥,批量免密操作!
使用命令ssh-keygen 需要手动敲击回车,才会生成密钥,如下代码所示 [rootlocalhost ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase):…...
C/C++开发,无可避免的内存管理(篇四)-智能指针备选
一、智能指针 采用C/C开发堆内存管理无论是底层开发还是上层应用,无论是开发新手,还是多年的老手,都会不自觉中招,尤其是那些不是自己一手经历的代码,要追溯问题出在哪里更是个麻烦事。C/C程序常常会遇到程序突然退出&…...
VMware ESXi给虚拟机扩容
用ESXi管理的虚拟机硬盘空间不够了,讲一下如何进行扩容。 一、查看现状 通过如下三个命令,可以查看硬盘情况,可以看到只有500G,已经用了45%。这次我们再扩容500G。 df -Th lsblk fdisk -lIDE磁盘的文件名为 /de…...
认识STM32和如何构建STM32工程
STM32介绍什么是单片机单片机(Single-Chip Microcomputer)是一种集成电路芯片,把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种/0口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电…...
RabbitMQ延迟队列
目录 一、概念 二、使用场景 三、RabbitMQ 中的 TTL (一)队列设置 TTL (二)消息设置 TTL (三)两者的区别 四、整合SpringBoot实现延迟队列 (一)创建项目 (二&am…...
Java中常用的七种队列你了解多少?
文章目录Java中常用的七种队列你了解多少?ArrayBlockingQueue队列如何使用?添加元素到队列获取队列中的元素遍历队列LinkedBlockingQueue队列如何使用?1. 创建SynchronousQueue对象2. 添加元素到队列3. 获取队列中的元素4. 遍历队列SynchronousQueue队列…...
<Java获取时间日期工具类>常见八种场景(一)
一:自定义时间日期工具类常用的八种方式(整理): 0,getTimeSecondNum:时间日期转成秒数,常用于大小比较 1,getLastYearMonthLastDay:获取去年当月最后一天的时间日期 2,getLastYearM…...
接上一篇 对多个模型环形旋转进行优化 指定旋转位置
using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; public class ModelAnimal : MonoBehaviour { //记录鼠标滑动 public Vector2 lastPos;//鼠标上次位置 Vector2 currPos;//鼠标当前位置 Vector2 offset;//两次位置的偏移…...
Unity中获取地形的法线
序之前,生成了地形图:(42条消息) 从灰度图到地形图_averagePerson的博客-CSDN博客那末,地形的法线贴图怎么获取?大概分为两个部分吧,先拿到法线数据,再画到纹理中去。关于法线计算Unity - Scripting API: M…...
模型解释性:PFI、PDP、ICE等包的用法
本篇主要介绍几种其他较常用的模型解释性方法。 1. Permutation Feature Importance(PFI) 1.1 算法原理 置换特征重要性(Permutation Feature Importance)的概念很简单,其衡量特征重要性的方法如下:计算特征改变后模型预测误差的增加。如果打乱该特征的…...
spring常见面试题(2023最新)
目录前言1.spring是什么2.spring的设计核心是什么3.IOC和AOP面试题4.spring的优点和缺点5.spring中bean的作用域6.spring中bean的注入方式7.BeanFactory 和 ApplicationContext有什么区别?8.循环依赖的情况,怎么解决?9.spring中单例Bean是线程…...
华为OD机试题,用 Java 解【压缩报文还原】问题
最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...
wordpress编辑主页/网站申请流程
非常简单的发送邮件实现,网上有很多啦,但还是自己写写记录下吧。 package cn.jmail.test;import java.util.Properties;import javax.mail.*; import javax.mail.internet.*;public class FirstMail {/*** 发送简单邮件方法* param host 发送邮件服务…...
济南集团网站建设方案/互联网广告优势
Android5.0中向我们介绍了一个全新的控件–CardView,从本质上看,可以将CardView看做是FrameLayout在自身之上添加了圆角和阴影效果。请注意:CardView被包装为一种布局,并且经常在ListView和RecyclerView的Item布局中,作…...
湘潭公司做网站/创建网站的公司
前言 由于本人参加面试,但是JVM这块回答的十分不好,问了面试官,面试官说我基础不行!我真的不行,所以看过的不一定能理解,感觉之前就是糊弄任务,然后这次等实训结束,啥都干完了&#…...
油金地 做网站/seo工具网站
应用“慎独”的最高境界是......程序调节胰岛素分泌的最重要因素是入口传导慢痛的外周神经纤维主要是某疟疾患者突发畏寒、方法寒战、体温高达39℃,这主要是由于其声妊娠期乳腺组织具备泌乳能力却不泌乳的原因是明格下述哪项不是化学性突触的结构特点关于抑制性突触…...
网站pr查询/深圳优化公司哪家好
成绩表score的结构: 如何查询每门课程最高分的学生的学号,课程号,成绩? 答案: select t1.sid,t1.cid,t1.score from score t1 where t1.score (select max(t2.score)from score t2where t2.cid t1.cidgroup by t2.c…...
贵港网站建设公司/seo报价单
v-bind 有三种修饰符,分别为 .sync、.once、.camel。.sync : 用于组件props属性,进行双向绑定,即父组件绑定传递给子组件的值,无论在哪个组件中对其进行了修改,其他组件中的这个值也会随之更新。案例背景爸爸给儿子钱&…...