RocketMQ消息队列(二)—— Go语言操作RocketMQ

上篇文章《RocketMQ消息队列(一)------ 基本概念和消息类型》记录了RocketMQ的一些基本的概念,本文主要写几个go语言操作RocketMQ的示例代码

一、发送普通消息

go 复制代码
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"
)

func main() {
	p, err := rocketmq.NewProducer(
		producer.WithNsResolver(primitive.NewPassthroughResolver([]string{"127.0.0.1:9876"})),
		producer.WithRetry(2), //指定重试次数
	)
	if err != nil {
		panic(err)
	}
	if err = p.Start(); err != nil {
		panic("启动producer失败")
	}
	topic := "test"
	// 构建一个消息
	message := primitive.NewMessage(topic, []byte("hello world!"))
	res, err := p.SendSync(context.Background(), message)
	if err != nil {
		fmt.Printf("send message error: %s\n", err)
	} else {
		fmt.Printf("send message success: result=%s\n", res.String())
	}
	if err = p.Shutdown(); err != nil {
		panic("关闭producer失败")
	}
}

二、消费消息

go 复制代码
import (
	"context"
	"fmt"
	"github.com/apache/rocketmq-client-go/v2"
	"github.com/apache/rocketmq-client-go/v2/consumer"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"time"
)

func main() {
	c, err := rocketmq.NewPushConsumer(
		consumer.WithGroupName("test"),
		consumer.WithNsResolver(primitive.NewPassthroughResolver([]string{"127.0.0.1:9876"})),
	)
	if err != nil {
		panic(err)
	}
	if err := c.Subscribe("test",
		consumer.MessageSelector{},
		// 收到消息后的回调函数
		func(ctx context.Context, msgs ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
			for i := range msgs {
				fmt.Printf("获取到值: %v \n", msgs[i])
			}
			return consumer.ConsumeSuccess, nil
		}); err != nil {
	}
	err = c.Start()
	if err != nil {
		panic("启动consumer失败")
	}
	//不能让主goroutine退出
	time.Sleep(time.Hour)
	_ = c.Shutdown()
}

三、发送延迟消息

延迟消息和普通的发送区别就是在需要发送的消息上,用下面的代码设置发送的级别即可

go 复制代码
message.WithDelayTimeLevel(3)

全部代码如下:

go 复制代码
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"
)

func main() {
	p, err := rocketmq.NewProducer(
		producer.WithNsResolver(primitive.NewPassthroughResolver([]string{"127.0.0.1:9876"})),
		producer.WithRetry(2), //指定重试次数
	)
	if err != nil {
		panic(err)
	}
	if err = p.Start(); err != nil {
		panic("启动producer失败")
	}
	topic := "test"
	// 构建一个消息
	message := primitive.NewMessage(topic, []byte("this is a delay message!"))
	// 给message设置延迟级别
	message.WithDelayTimeLevel(3)
	res, err := p.SendSync(context.Background(), message)
	if err != nil {
		fmt.Printf("send message error: %s\n", err)
	} else {
		fmt.Printf("send message success: result=%s\n", res.String())
	}
	if err = p.Shutdown(); err != nil {
		panic("关闭producer失败")
	}
}

四、发送事务消息

发送事务消息需要我们写一个TransactionListener接口的方法,指明事务执行成功和回调的具体操作,接口如下

go 复制代码
type TransactionListener interface {
	//  When send transactional prepare(half) message succeed, this method will be invoked to execute local transaction.
	ExecuteLocalTransaction(*Message) LocalTransactionState

	// When no response to prepare(half) message. broker will send check message to check the transaction status, and this
	// method will be invoked to get local transaction status.
	CheckLocalTransaction(*MessageExt) LocalTransactionState
}

完整的代码如下:

go 复制代码
import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/apache/rocketmq-client-go/v2"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/apache/rocketmq-client-go/v2/producer"
)

type DemoListener struct {
}

func (dl *DemoListener) ExecuteLocalTransaction(msg *primitive.Message) primitive.LocalTransactionState {
	fmt.Println("开始执行本地逻辑")
	time.Sleep(time.Second * 3)
	fmt.Println("执行本地逻辑失败")
	//本地执行逻辑无缘无故失败 代码异常 宕机
	return primitive.UnknowState
}

func (dl *DemoListener) CheckLocalTransaction(msg *primitive.MessageExt) primitive.LocalTransactionState {
	fmt.Println("rocketmq的消息回查")
	return primitive.CommitMessageState
}

func main() {
	p, _ := rocketmq.NewTransactionProducer(
		&DemoListener{},
		producer.WithNsResolver(primitive.NewPassthroughResolver([]string{"127.0.0.1:9876"})),
		producer.WithRetry(1),
	)
	err := p.Start()
	if err != nil {
		fmt.Printf("start producer error: %s\n", err.Error())
		os.Exit(1)
	}

	res, err := p.SendMessageInTransaction(context.Background(),
		primitive.NewMessage("TopicTest5", []byte("Hello RocketMQ again ")))

	if err != nil {
		fmt.Printf("send message error: %s\n", err)
	} else {
		fmt.Printf("send message success: result=%s\n", res.String())
	}

	time.Sleep(5 * time.Minute)
	err = p.Shutdown()
	if err != nil {
		fmt.Printf("shutdown producer error: %s", err.Error())
	}
}

后记

个人总结,欢迎转载、评论、批评指正

相关推荐
阿里云云原生2 天前
海量接入、毫秒响应:易易互联携手阿里云构筑高可用物联网消息中枢
rocketmq
侃侃_天下2 天前
最终的信号类
开发语言·c++·算法
echoarts2 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix2 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题2 天前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说2 天前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔2 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号2 天前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_2 天前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty2 天前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序