发送定时消息
分布式消息服务RocketMQ版支持任意时间的定时消息,最大推迟时间可达到1年。
定时消息即生产者生产消息到分布式消息服务RocketMQ版后,消息不会立即被消费,而是延迟到设定的时间点后才会发送给消费者进行消费。
发送定时消息前,请参考收集连接信息收集RocketMQ所需的连接信息。
适用场景
定时消息适用于以下场景:
- 消息对应的业务逻辑有时间窗口要求,如电商交易中超时未支付关闭订单的场景。在订单创建时发送一条定时消息,5分钟以后投递给消费者,消费者收到此消息后需要判断对应订单是否完成支付,如果未完成支付,则关闭订单。如果已完成,则忽略。
 - 通过消息触发定时任务的场景,如在某些固定时间点向用户发送提醒消息。
 
注意事项
- 4.8.0版本定时消息的最大延迟时间为1年,5.x版本为7天,若延迟时间超过对应版本的最大限制(1年或7天),消息将发送失败。
 - 定时消息的定时时间如果被设置成当前时间戳之前的某个时刻,消息将立刻投递给消费者。
 - 无法确保定时消息仅投递一次,定时消息可能会重复投递。
 - 定时消息的定时时间是服务端开始向消费端投递的时间。如果消费者当前有消息堆积,那么定时消息会排在堆积消息后面,将不能严格按照配置的时间进行投递。
 - 由于客户端和服务端可能存在时间差,消息的实际投递时间与客户端设置的投递时间之间可能存在偏差,以服务端时间为准。
 - 设置定时消息的投递时间后,依然受消息老化时间限制,默认消息老化时间为2天。例如,设置定时消息5天后才能被消费,如果第5天后一直没被消费,那么这条消息将在第7天被删除。
 - 定时消息将占用普通消息约3倍的存储空间,大量使用定时消息时需要注意存储空间占用。
 
准备环境
- 执行以下命令,检查是否已安装Go。
    
go version
返回如下回显时,说明Go已经安装。
go version go1.16.5 linux/amd64
如果未安装Go,请下载并安装。
 - 进入Go脚本所在的bin目录下。
 - 执行“touch go.mod”命令新建一个“go.mod”,并增加以下代码,添加依赖。
    
module rocketmq-example-go go 1.13 require ( github.com/apache/rocketmq-client-go/v2 v2.1.2 )
 - 执行如下命令增加代理。
    
export GOPROXY=https://goproxy.cn,direct
 - 执行如下命令下载依赖。
    
go mod tidy
 
发送定时消息
发送定时消息的示例代码如下(以下加粗内容需要替换为实例自有信息,请根据实际情况替换)。
package main
import (
	"context"
	"fmt"
	"github.com/apache/rocketmq-client-go/v2"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/apache/rocketmq-client-go/v2/producer"
	"os"
)
func main() {
	p, _ := rocketmq.NewProducer(
		producer.WithNsResolver(primitive.NewPassthroughResolver([]string{"192.168.0.1:8100"})),
		producer.WithRetry(2),
		//producer.WithTls(true), //创建实例时,如果开启了SSL,请添加此行代码。
	)
	err := p.Start()
	if err != nil {
		fmt.Printf("start producer error: %s", err.Error())
		os.Exit(1)
	}
	msg := primitive.NewMessage("test", []byte("Hello RocketMQ Go Client!"))
	msg.WithProperty("__STARTDELIVERTIME", strconv.FormatInt(time.Now().UnixMilli()+3000, 10))
	res, err := p.SendSync(context.Background(), msg)
	if err != nil {
		fmt.Printf("send message error: %s\n", err)
	} else {
		fmt.Printf("send message success: result=%s\n", res.String())
	}
	err = p.Shutdown()
	if err != nil {
		fmt.Printf("shutdown producer error: %s", err.Error())
	}
}
  示例代码中的参数说明如下,请参考收集连接信息获取参数值。
- 192.168.0.1:8100:表示实例连接地址和端口。
 - test:表示Topic名称。