go: rocketmq

·  阅读 14
go: rocketmq

0/参考网址

blog.csdn.net/qq_28119741…

0/依赖的库包

github.com/apache/rocketmq-client-go/v2
复制代码

1/初始化

// 定义一个结构体
type MqConf struct {
   NameServers []string `mapstructure:"nameServers"`
}

// 声明几个变量
var (
    MqProducer            rocketmq.Producer
    MqPushConsumerSuccess rocketmq.PushConsumer
    MqPushConsumerFail    rocketmq.PushConsumer
    MqPushConsumerDelay   rocketmq.PushConsumer
)

// 声明一个常亮
const (
	MqRetryTimes = 3  // 重试的次数
)

// 初始化mq
// mqConf是结构体MqConf的一个实例化对象,是mq的一些配置
func InitMq(mqConf *MqConf) {
        // 如果是空,则panic,直接报错,没有mq的配置
	if mqConf == nil {
		panic("mq config is nil")
		return
	}
        // 声明一个err的错误变量
	var err error
           
        //////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////
        // 定义生产者
	MqProducer, err = rocketmq.NewProducer(
	   producer.WithGroupName("notify_producer"),   // 组的名字
	   producer.WithNameServer(mqConf.NameServers), // 服务的名字
	   producer.WithRetry(MqRetryTimes),            // 重试的次数
	)
	if err != nil {
	   panic(fmt.Sprintf("init rocket mq producer err:%v", err))
	   return
	}
         
        // 启动生产者
	err = MqProducer.Start()
	if err != nil {
	    panic(fmt.Sprintf("producer mq start err:%v", err))
	    return
	}
        
        //////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////
        // 定义消费者
	MqPushConsumerSuccess, err = rocketmq.NewPushConsumer(
            consumer.WithGroupName("notify_consumer_success"),
            consumer.WithNameServer(mqConf.NameServers),
	)
	if err != nil {
            panic(fmt.Sprintf("init rocket mq push consumer err:%v", err))
            return
	}
        
        // 定义消费者
	MqPushConsumerFail, err = rocketmq.NewPushConsumer(
            consumer.WithGroupName("notify_consumer_fail"),
            consumer.WithNameServer(mqConf.NameServers),
	)
	if err != nil {
		panic(fmt.Sprintf("init rocket mq push consumer err:%v", err))
		return
	}
        
        // 定义消费者
	MqPushConsumerDelay, err = rocketmq.NewPushConsumer(
            consumer.WithGroupName("notify_consumer_delay"),
            consumer.WithNameServer(mqConf.NameServers),
	)
	if err != nil {
            panic(fmt.Sprintf("init rocket mq push consumer err:%v", err))
            return
	}
 
}
 
func ShutDownMq() {
    _ = MqProducer.Shutdown()
    _ = MqPushConsumerSuccess.Shutdown()
    _ = MqPushConsumerFail.Shutdown()
    _ = MqPushConsumerDelay.Shutdown()
}

//这里生产者只实例化了一个,然后可以启动了。

//消费者如果是多个topic或者多个tag需要实例化多个

//即:同一group下的所有消费者应该订阅的topic和tag都是相同的

//同一group下的topic相同,但tag订阅不同也是不行的

//否则会导致rebalance导致consumer只消费一部分topic

//消费者可以订阅多个topic或者tag,但是同一组内的订阅的关系必须一致

//只实例化一次即可,定义全局变量或者单例都可以

复制代码

订阅

func SubScribe() {
	var err error
	err = conf.MqPushConsumerSuccess.Subscribe(include.TopicNotifySucess, consumer.MessageSelector{}, callBackSucc)
	if err != nil {
		panic(fmt.Sprintf("consumer subscribe TopicNotifySucess err:%v", err))
		return
	}
 
	err = conf.MqPushConsumerFail.Subscribe(include.TopicNotifyFail, consumer.MessageSelector{}, callBackFail)
	if err != nil {
		panic(fmt.Sprintf("consumer subscribe TopicNotifyFail err:%v", err))
		return
	}
 
	err = conf.MqPushConsumerDelay.Subscribe(include.TopicNotifyDelay, consumer.MessageSelector{}, callBackTimeOut)
	if err != nil {
		panic(fmt.Sprintf("consumer subscribe TopicNotifyDelay err:%v", err))
		return
	}
 
	err = conf.MqPushConsumerSuccess.Start()
	if err != nil {
		panic(fmt.Sprintf("MqPushConsumerSuccess start err:%v", err))
		return
	}
 
	err = conf.MqPushConsumerFail.Start()
	if err != nil {
		panic(fmt.Sprintf("MqPushConsumerFail start err:%v", err))
		return
	}
 
	err = conf.MqPushConsumerDelay.Start()
	if err != nil {
		panic(fmt.Sprintf("MqPushConsumerDelay start err:%v", err))
		return
	}
 
}
func callBackSucc(ctx context.Context, msgs ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
 
	for i := range msgs {
        fmt.Println(string(msgs[i].Body))
	}
	return consumer.ConsumeSuccess, nil
}
 
func callBackFail(ctx context.Context, msgs ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
 
	for i := range msgs {
		fmt.Println(string(msgs[i].Body))
	}
	return consumer.ConsumeSuccess, nil
}
 
func callBackTimeOut(ctx context.Context, msgs ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
 
	for i := range msgs {
		fmt.Println(string(msgs[i].Body))
	}
	return consumer.ConsumeSuccess, nil
}
复制代码

发送消息

// 声明几个常量
const (
    RetryTime = 3
    SleepTime = time.Millisecond * 10
)

// 发送成功
func SendSuccNotifyByMq(taskID string) (err error) {
    // 这里是构建了一个msg,就是要发送的内容到topic
    msg := primitive.NewMessage(include.TopicNotifySucess, []byte(taskID))
    
    // msg.WithTag(include.TagSuccNotify)
    
    // 每条msg尝试发送3次
    for i := 0; i < RetryTime; i++ {
        res, err := conf.MqProducer.SendSync(context.Background(), msg)
        if err != nil {
            // 如果这次发送失败了,则sleep一会,一会再接着发
            time.Sleep(SleepTime)
            continue  // 一会接着发
        }
        // 如果在RetryTime的次数内,一直都是发送失败,则break,跳出for循环
        break
    }
    return
}

// 发送失败
func SendFailNotifyByMq(taskID string) (err error) {
    // 这里是构建了一个msg,就是要发送的内容到topic
    msg := primitive.NewMessage(include.TopicNotifyFail, []byte(taskID))
    
    // msg.WithTag(include.TagFailNotify) 
    // 如果要发送带tag的加上这个
    
    for i := 0; i < RetryTime; i++ {
        res, err := conf.MqProducer.SendSync(context.Background(), msg)
        if err != nil {
            time.Sleep(SleepTime)
            continue
        }
        break
    }
    return
}
 
// 发送延时消息
// 有的场景中,有的业务中,我们需要延迟发送消息到topic
// 及时的识别出之后,并不是要实时的发送到topic,有的时候需要延迟发送msg到topic
func SendDelayNotifyByMq(taskID string) (err error) {
    // 这里是构建了一个msg,就是要发送的内容到topic
    msg := primitive.NewMessage(include.TopicNotifyDelay, []byte(taskID))

    msg.WithDelayTimeLevel(conf.C.DelayTime)
    
    for i := 0; i < RetryTime; i++ {
        res, err := conf.MqProducer.SendSync(context.Background(), msg)
        if err != nil {
            time.Sleep(SleepTime)
            continue
        }
        break
    }
    return
}
复制代码
分类:
开发工具
标签:
收藏成功!
已添加到「」, 点击更改