基于rabbitmq实现的延时队列(golang版)

Golang RabbitMQ实现的延时队列 之前做秒杀商城项目的时候使用到了延时队列来解决订单超时问题,本博客就总结一下Golang是如何利用RabbitMQ实现的延时队列的。 阅读详情

虽然 rabbitmq 没有延时队列的功能,但是稍微变动一下也是可以实现的

实现延时队列的基本要素

  1. 存在一个倒计时机制:Time To Live(TTL)
  2. 当到达时间点的时候会触发一个发送消息的事件:Dead Letter Exchanges(DLX)
           ~~~~~~       基于第一点,我利用的是消息存在过期时间这一特性, 消息一旦过期就会变成dead letter,可以让单独的消息过期,也可以设置整个队列消息的过期时间 而rabbitmq会有限取两个值的最小
           ~~~~~~       基于第二点,是用到了rabbitmq的过期消息处理机制: . x-dead-letter-exchange 将过期的消息发送到指定的 exchange 中 . x-dead-letter-routing-key 将过期的消息发送到自定的 route当中

在这里例子当中,我使用的是 过期消息+转发指定exchange

在 golang 中的实现

首先是消费者comsumer.go

package main

import (
	"log"

	"github.com/streadway/amqp"
)

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}


func main() {
	// 建立链接
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	failOnError(err, "Failed to connect to RabbitMQ")
	defer conn.Close()

	ch, err := conn.Channel()
	failOnError(err, "Failed to open a channel")
	defer ch.Close()

	// 声明一个主要使用的 exchange
	err = ch.ExchangeDeclare(
		"logs",   // name
		"fanout", // type
		true,     // durable
		false,    // auto-deleted
		false,    // internal
		false,    // no-wait
		nil,      // arguments
	)
	failOnError(err, "Failed to declare an exchange")

	// 声明一个常规的队列, 其实这个也没必要声明,因为 exchange 会默认绑定一个队列
	q, err := ch.QueueDeclare(
		"test_logs",    // name
		false, // durable
		false, // delete when unused
		true,  // exclusive
		false, // no-wait
		nil,   // arguments
	)
	failOnError(err, "Failed to declare a queue")

    /**
     * 注意,这里是重点!!!!!
     * 声明一个延时队列, ß我们的延时消息就是要发送到这里
     */
	_, errDelay := ch.QueueDeclare(
		"test_delay",    // name
		false, // durable
		false, // delete when unused
		true,  // exclusive
		false, // no-wait
		amqp.Table{
			// 当消息过期时把消息发送到 logs 这个 exchange
			"x-dead-letter-exchange":"logs",
		},   // arguments
	)
	failOnError(errDelay, "Failed to declare a delay_queue")

	err = ch.QueueBind(
		q.Name, // queue name, 这里指的是 test_logs
		"",     // routing key
		"logs", // exchange
		false,
		nil)
	failOnError(err, "Failed to bind a queue")

	// 这里监听的是 test_logs
	msgs, err := ch.Consume(
		q.Name, // queue name, 这里指的是 test_logs
		"",     // consumer
		true,   // auto-ack
		false,  // exclusive
		false,  // no-local
		false,  // no-wait
		nil,    // args
	)
	failOnError(err, "Failed to register a consumer")

	forever := make(chan bool)

	go func() {
		for d := range msgs {
			log.Printf(" [x] %s", d.Body)
		}
	}()

	log.Printf(" [*] Waiting for logs. To exit press CTRL+C")
	<-forever
}

然后是生产者productor.go

package main

import (
	"log"
	"os"
	"strings"

	"github.com/streadway/amqp"
)

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}

func main() {
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	failOnError(err, "Failed to connect to RabbitMQ")
	defer conn.Close()

	ch, err := conn.Channel()
	failOnError(err, "Failed to open a channel")
	defer ch.Close()

	body := bodyFrom(os.Args)
	// 将消息发送到延时队列上
	err = ch.Publish(
		"", 				// exchange 这里为空则不选择 exchange
		"test_delay",     	// routing key
		false,  			// mandatory
		false,  			// immediate
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        []byte(body),
			Expiration: "5000",	// 设置五秒的过期时间
		})
	failOnError(err, "Failed to publish a message")

	log.Printf(" [x] Sent %s", body)
}

func bodyFrom(args []string) string {
	var s string
	if (len(args) < 2) || os.Args[1] == "" {
		s = "hello"
	} else {
		s = strings.Join(args[1:], " ")
	}
	return s
}
go run comsumer.go
go run productor.go

具体看代码和注释就行, 这里的关键点就是将要延时的消息发送到过期队列当中, 然后监听的是过期队列转发到的 exchange 下的队列 正常情况就是始终监听一个队列,然后把过期消息发送到延时队列中,当消息到达时间后就把消息发到正在监听的队列

本文转至:https://blog.justwe.site/post/go-rabbitmq-delay-queue/

订单中心模块:Go语言构建高并发订单系统的工程实践 本文基于Go语言实现了一个生产级订单中心系统,针对电商场景下的订单管理核心挑战提出了完整解决方案。系统采用模块化设计,包含以下关键技术: 状态机引擎:使用go-statemachine管理10+订单状态流转,确保状态变更合法性和可追溯性 分布式事务:集成Seata-golang实现下单、库存扣减、优惠券使用的事务一致性 分库分表:通过ShardingSphere-Proxy实现按user_id取模的8表分片方案 延时队列:基于RabbitMQ的TTL+DLX机制实现30分钟自动关单 限流保护:采用Senti 阅读详情

相关推荐

Go-delay-queue基于Redis实现的延迟队列

延迟队列, 参考有赞延迟队列设计实现

Golang-RabbitMQ 延迟队列的两种实现方法【详解】

我们在运行消费者之后,先发送一个存活时间为 15s 的消息,随后立刻发送一个存活时间为 5s 的消息,按照功能来讲,5s 消息应该先成为死信然后被消费,随后是 15s 消息,但实际是 15s 后,15s 消息和 5s 消息几乎同时一前一后同时被消费。生产者将消息设定好 TTL 发送到延迟队列前,会先由主交换机发送到默认的普通队列里存活设定好的时间,时间到后由死信交换机路由到死信队列,消费者只需对死信队列进行监听,取出消息消费即可。,被推送到死信交换机上后,被路由到死信队列,然后由消费者从死信队列中消费。

Pillow_Monkey的博客 1651

5种主流触觉传感器对比:GelSight、DIGIT、Taxim、GelSlim和TACTO如何选?

本文深度解析了GelSight、DIGIT、Taxim、GelSlim和TACTO五款主流触觉传感器的技术原理与核心特性。通过对比视觉传感与电学传感两大技术路径,为机器人灵巧抓取、精密检测等应用场景提供清晰的选型决策指南,帮助开发者根据项目需求在分辨率、响应速度、集成度与成本之间找到最佳平衡。

Black的专栏 931

go rabbitmq 延时队列代码实现 (延时插件 x-delayed-message)

rabbitmq延时队列有 x-delayed-message 插件,我上一篇有如何安装延时插件说明。另使用的包是 github.com/streadway/amqp go get 一下即可。通过生产者发送不同延时消息,消费者能收到对应延时的消息,不会因为消息的前后顺序而阻塞。建一个包,用于封装生产者的一些操作。

leo_jk的博客 485

六轴机器人正解

采用的是John H.Craig在【机器人学导论】中的改进DH模型 1.六轴坐标系 2.DH参数 i αi−1\alpha_{i-1}αi−1​ ai−1a_{i-1}ai−1​ did_idi​ θi\theta_iθi​初值 1 0 0 0 0 2 -90 a1a_1a1​ 0 -90 3 0 a2a_2a2​ 0 -90 4 -90 a3a_3a3​ d4d...

m0_37581770的博客 2511

【信创-k8s】银河麒麟V10国防版+鲲鹏/飞腾(arm64架构)在线/离线部署k8s1.30+kubesphere

银河麒麟作为国家核高基专项的重要成果,国防版凭借其卓越的安全性和可靠性,已成为军工领域的首选操作系统。之前我们在适配麒麟V4国防版的过程中已发现诸多安全性要求,而麒麟V10国防版在安全防护等级上又达到了更高的级别。本文将主要演示离线部署,因为军工项目基本不会出现联网场景。即使在线,也可以按离线方式部署,且离线部署由于有私有仓库,不会存在镜像获取不到和丢失情况。

2023年最新地推相关信息 542

golang rabbitmq实现的延时队列

golang 采用RabbitMQ官方延迟插件实现延时队列 x-delayed-message

John_lidong的博客 2986

IEC61850客户端连接实战:CMS vs MMS协议抓包对比与性能初探(基于YX-PIS协议栈)

本文深入探讨了IEC61850客户端连接中CMS与MMS协议的抓包对比与性能优化。通过Wireshark抓包分析、协议栈配置实战和性能基准测试,揭示了两种协议在连接建立、数据交互和性能调优方面的关键差异,为智能电网自动化系统的协议选择提供了实用指南。

weixin_29209805的博客 215

go通过rabbitmq实现延迟队列

go通过rabbitmq实现延迟队列

weixin_38155824的博客 1774

一个中科大差生的8年程序员工作总结

今年终于从大菊花厂离职了,离职前收入大概60w不到吧,在某乎属于比较差的,今天终于有空写一下自己的职场故事,也算是给自己近8年的程序员工作做个总结复盘。近8年有些事情做对了,也有更多事情做错了,在这里记录一下,希望能够给后人一些帮助吧,也欢迎私信交流。文笔不好,见谅,有些细节记不清了,如果有出入,就当是我编的这个故事吧。 PS:有几个问题先在这里解释一下,评论就不一一回复了 1、关于差生,我本人在科大时确实成绩偏下,差生主要讲这一点,没其他意思。 2、因为买房是我人生中的大事,我认为需要记录和总结一下

陈小房的自我修炼 5万+

基于通义千问2.5-7B-Instruct的技术深度解析

通义千问2.5-7B-Instruct是一个基于Transformer架构的大型语言模型,具有70亿参数。它通过自注意力机制和前馈神经网络处理输入序列,能够捕捉长距离依赖关系,适用于多种NLP任务。微调是指在预训练模型的基础上,使用特定任务的数据进行进一步训练,以使模型更好地适应特定任务。微调可以显著提高模型在特定任务上的性能。通义千问2.5-7B-Instruct是一个强大的语言模型,适用于多种NLP任务。通过深入理解其架构、微调方法和核心代码,可以更好地应用于实际场景。

zhangjiaofa的专栏 1569

RabbitMQ没有延时队列?学会这一招玩转延时队列_rabbit延迟队列创建不了

延时队列:顾名思义,是一个用于做消息延时消费的队列。但是它也是一个普通队列,所以它具备普通队列的特性,相比之下,延时的特性就是它最大的特点。所谓的延时就是将我们需要的消息,延迟多久之后被消费。普通队列是即时消费的,延时队列是根据延时时间,多久之后才能消费的。

2401_84254555的博客 1304

加密算法:深度解析Ed25519原理

在 Solana 开发过程中,我一直对 Ed25519 加密算法 如何生成公钥、签名以及验证签名的机制感到困惑。为了弄清这一点,我查阅了大量相关资料,终于对其流程有了更清晰的理解。在此记录实现过程,方便日后查阅。

盹猫的博客 1万+

RabbitMQ没有延时队列?学会这一招玩转延时队列_rabbit延迟队列创建不了(1)

核心的应用内容基本都是基于需要设定过期时间的。

2401_84910848的博客 413

yolov5 FPGA实现及verilog代码仿真

本文介绍了一种基于FPGA的卷积神经网络加速器设计,采用混合架构实现网络功能。该系统将训练和图像预处理等复杂计算保留在PC端执行,仅将主干网络部署在FPGA上。由于片上资源限制,建议通过外接DDR存储扩展容量。文章提供了完整的Verilog HDL源码,包括卷积单元(convUnit)、卷积层(convLayerSingle)和处理单元(processingElement)等核心模块,均已通过仿真验证。该设计采用流水线结构,使用浮点运算单元实现卷积计算,支持32x32图像输入和5x5卷积核处理。系统架构图中

QQ_778132974的博客 576

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

延时队列的几种实现方案比较

背景 项目涉及到了一个自动过单的问题,24小时后无人操作,自动通过什么的。所以,为了实现这个功能,决定采用延时队列。那么,如何实现一个延时队列呢?我去各大博客进行了技术调研,整理了一下几种方法。供大家参考,也希望大家评论区提出更多的方法 技术方案 基于redis的延时队列 基于DelayQueue的延时队列(java) 实现原理主要是利用了PriorityQueue这个类,内部是一个平衡二叉树,满足一定条件的时候,会取消返回数据,让阻塞等待数据的经常继续执行。以此实现的阻塞功能。 基于定时的实现 各个语言应

qq_42031483的博客 2620

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Rabbitmq实现延迟队列

在RabbitMQ中实现延迟队列(延时队列)可以有几种方案,其中常用的是通过死信队列(Dead Letter Queue,DLX)和rabbitmq_delayed_message_exchange插件来实现。以下是这两种方案的介绍以及注意事项。

qq_37638125的博客 966

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【外行也能看懂的RabbitMQ系列(四)】—— RabbitMQ进阶篇之通过插件实现延迟队列(内含实现代码及rabbitmq_delayed_message_exchange安装)

恭喜所有看到本篇文章的小伙伴,成功解锁了RabbitMQ系列之高级特性插件版延迟队列的内容通过本文,你将清楚的了解到:什么是延时队列?延时队列使用场景?如何安装安装延时队列插件(rabbitmq_delayed_message_exchange)?本文最后,小名将上一篇文章的实例做一些修改来实现新的效果

小名同学 27万+

基于 rabbitmq 实现的延时队列

虽然 rabbitmq 没有延时队列的功能,但是稍微变动一下也是可以实现的 实现延时队列的基本要素 存在一个倒计时机制:Time To Live(TTL) 当到达时间点的时候会触发一个发送消息的事件:Dead Letter Exchanges(DLX) 基于第一点,我利用的是消息存在过期时间这一特性, 消息一旦过期就会变成dead l...

weixin_34332905的博客 278

用户下订单之后15分钟支付实现_订单15分钟未支付超时取消-延时队列-Go语言中文社区...

延迟队列,顾名思义它是一种带有延迟功能的消息队列。 那么,是在什么场景下我才需要这样的队列呢?一、背景先看看一下业务场景:1.会员过期前3天发送召回通知2.订单支付成功后,5分钟后检测下游环节是否都正常,比如用户购买会员后,各种会员状态是否都设置成功3.如何定期检查处于退款状态的订单是否已经退款成功?4.实现通知失败,1,3,5,7分钟重复通知,直到对方回复?通常解决以上问题,最简单直接的办法就是...

weixin_39963174的博客 1628

延时消息_go 基于rabbitmq 实现延时消息

最近因为项目需要,需要实现延时消息,正好使用rabbitmq来实现。概述rabbitmq可以对消息和队列设置TTL,可以对消息单独进行设置。这里我使用了rabbitmq的过期消息处理机制:x-dead-letter-exchange 将过期消息发送到执行的exchange中,x-dead-letter-routing-key 将过期消息发送到指定的路由中实现消费者package mq_time ...

weixin_29522501的博客 482

go rabbitmq使用实例,延时队列使用实例

go 使用rabbitmq,rabbitmq延时队列的代码示例

weixin_44540711的博客 552

一口气说出 6种 延时队列的实现方法,面试官也得服

一、延时队列的应用什么是延时队列?顾名思义:首先它要具有队列的特性,再给它附加一个延迟消费队列消息的功能,也就是说可以指定队列中的消息在哪个时间点被消费。延时队列在项目中的应用还是比较多...

HollisChuang's Blog 1275

延时队列的几种实现方式(只有原理,并没有源码)

延时队列 需求描述 场景一 在淘宝下了订单,过半个小时未支付就取消订单 场景二 还是淘宝(别问,问就是淘宝资深剁手党),发货后超过15天未确认就自动收货 需求分析 ​ 本质上都是超过xxx时间,就异步去做一件事。说到异步那基本上就是搞个定时任务去轮询或者消息队列+轮询。基本上有几种实现方式,挨个看一下。 实现方式 DelayQueue+Delayed Java的并发包java.util.concurrent下提供了延时队列DelayQueue,它内部维护了一个优先级队列PriorityQueue来维护任

你知道的越多,你不知道的越多 2084

RabbitMQ 从原理到实战—golang版本

RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。特点:基于AMQP协议来实现。主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。可靠性:采用一系列机制来确保消息的可靠性,如持久化、传输确认和发布确认等方法。

小张编程旅途的博客 1966
上一篇: golang 如何通过unsafe.Pointer uintptr来实现string与byte互转
下一篇: golang写的IM服务器(tcp,websocket,grpc)
cqims21
博客等级 码龄18年 4粉丝 12原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值