【奇技淫巧】借助RabbitMQ实现延时队列

686 阅读1分钟

MQ先知

MQ(消息队列)是后台开发者常用的中间件,先进先出的消息处理机制可以帮助后台服务之间进行解耦,从而适应当前微服务架构的趋势。目前业界主流MQ包括阿里MQ、IBM的WebSphere MQ、Kafka、RabbitMQ,开发者可以根据自身业务场景和对比报告进行选择。

延时队列

延时队列不会像普通队列一样及时处理消息,而是等待一段时间再去处理。应用场景,例如超过24小时退款、需求开发超过3天通知等。

RabbitMQ特殊在哪里

RabbitMQ本身不支持延时队列功能,但是它具备两个特性,一个是TTL(Time To Live)消息生存时间,一个是死信队列,一条消息如果在MQ中没有被消费,且停留时间超过了TTL,就会被扔进死信队列,这里的死信队列可以理解为一个新的MQ,可以被监听和被消费。

代码举例,将一条消息设置为6秒过期时间:

if err := channel.Publish(
    exchange, 
	routKey,  
	false,    
	false,
	amqp.Publishing{
		Expiration: "6000" // 设置消息的TTL为6秒  
		ContentType: "text/plain",
		Body:        []byte(body),
		Timestamp:   time.Now(),
	},
); err != nil {
	errMsg := fmt.Sprintf("Failed to msg Publish! err = %v", err)
	return errors.New(errMsg)
}

改造

利用RabbitMQ的TTL和死信队列进行改造,我们可以将等待时间设置为TTL,并且故意不去消费它,等到它过期之后,消息进入死信队列,再去异步处理,架构设计如下:

mq.png