docker-compose安装RocketMQ
docker-compose.yml
version: '3.8'
services:
namesrv:
image: apache/rocketmq:5.3.0
container_name: rmqnamesrv
ports:
- 9876:9876
networks:
- rocketmq
command: sh mqnamesrv
broker:
image: apache/rocketmq:5.3.0
container_name: rmqbroker
ports:
- 10909:10909
- 10911:10911
- 10912:10912
environment:
- NAMESRV_ADDR=rmqnamesrv:9876
depends_on:
- namesrv
networks:
- rocketmq
command: sh mqbroker
proxy:
image: apache/rocketmq:5.3.0
container_name: rmqproxy
networks:
- rocketmq
depends_on:
- broker
- namesrv
ports:
- 8080:8080
- 8081:8081
restart: on-failure
environment:
- NAMESRV_ADDR=rmqnamesrv:9876
command: sh mqproxy
networks:
rocketmq:
driver: bridge
docker-compose up -d
进入rmqbroker,创建topic,group
docker exec -it rmqbroker /bin/bash
topic
sh ./mqadmin updatetopic -n 192.168.252.128:9876 -c DefaultCluster -t demo_topic
group
sh ./mqadmin updateSubGroup -n 192.168.252.128:9876 -c DefaultCluster -g demo_group
rpc协议端口为8081
go生产者producer
package main
import (
"context"
"fmt"
"log"
"os"
"strconv"
"time"
"github.com/apache/rocketmq-clients/golang/v5"
"github.com/apache/rocketmq-clients/golang/v5/credentials"
)
const (
ConsumerGroup = "demo_group"
Topic = "demo_topic"
Endpoint = "192.168.252.128:8081"
AccessKey = "xxxxxx"
SecretKey = "xxxxxx"
)
func main() {
os.Setenv("mq.consoleAppender.enabled", "true")
golang.ResetLogger()
// In most case, you don't need to create many producers, singleton pattern is more recommended.
producer, err := golang.NewProducer(&golang.Config{
Endpoint: Endpoint,
Credentials: &credentials.SessionCredentials{
AccessKey: AccessKey,
AccessSecret: SecretKey,
},
},
golang.WithTopics(Topic),
)
if err != nil {
log.Fatal(err)
}
// start producer
err = producer.Start()
if err != nil {
log.Fatal(err)
}
// graceful stop producer
defer producer.GracefulStop()
for i := 0; i < 5; i++ {
// new a message
msg := &golang.Message{
Topic: Topic,
Body: []byte("我是消息内容 : " + strconv.Itoa(i+10)),
}
// set keys and tag
msg.SetKeys("a", "b")
msg.SetTag("ab")
// send message in sync
resp, err := producer.Send(context.TODO(), msg)
if err != nil {
log.Fatal(err)
}
for i := 0; i < len(resp); i++ {
fmt.Printf("%#v\n", resp[i])
}
// wait a moment
time.Sleep(time.Second * 1)
}
}
消费者 consumer
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/apache/rocketmq-clients/golang/v5"
"github.com/apache/rocketmq-clients/golang/v5/credentials"
)
const (
ConsumerGroup = "demo_group"
Topic = "demo_topic"
Endpoint = "192.168.252.128:8081"
AccessKey = "xxxxxx"
SecretKey = "xxxxxx"
)
var (
// maximum waiting time for receive func
awaitDuration = time.Second * 5
// maximum number of messages received at one time
maxMessageNum int32 = 16
// invisibleDuration should > 20s
invisibleDuration = time.Second * 20
// receive messages in a loop
)
func main() {
// log to console
os.Setenv("mq.consoleAppender.enabled", "true")
golang.ResetLogger()
// In most case, you don't need to create many consumers, singleton pattern is more recommended.
simpleConsumer, err := golang.NewSimpleConsumer(&golang.Config{
Endpoint: Endpoint,
ConsumerGroup: ConsumerGroup,
Credentials: &credentials.SessionCredentials{
AccessKey: AccessKey,
AccessSecret: SecretKey,
},
},
golang.WithAwaitDuration(awaitDuration),
golang.WithSubscriptionExpressions(map[string]*golang.FilterExpression{
Topic: golang.SUB_ALL,
}),
)
if err != nil {
log.Fatal(err)
}
// start simpleConsumer
err = simpleConsumer.Start()
if err != nil {
log.Fatal(err)
}
// graceful stop simpleConsumer
defer simpleConsumer.GracefulStop()
go func() {
for {
fmt.Println("开始接受消息")
mvs, err := simpleConsumer.Receive(context.TODO(), maxMessageNum, invisibleDuration)
if err != nil {
fmt.Println(err)
}
fmt.Println(len(mvs))
// ack message
for _, mv := range mvs {
//消息内容
fmt.Println(string(mv.GetBody()))
simpleConsumer.Ack(context.TODO(), mv)
fmt.Println(mv)
}
fmt.Println("wait a moment")
fmt.Println()
time.Sleep(time.Second * 3)
}
}()
// run for a while
time.Sleep(time.Minute)
}