目录
一、需要注意一个问题
客户端使用go-redis库 "github.com/go-redis/redis",不要使用"github.com/redis/go-redis/v9"
已知问题:
使用go-redis/v9 会带来消费消息延时上涨
二、代码如下
生产者:
package main
import (
"fmt"
"log"
"math/rand"
"time"
"github.com/go-redis/redis"
)
func publishTicketReceivedEvent(client *redis.Client) error {
log.Println("Publishing event to Redis")
startTime := time.Now().UnixNano() / 1000
err := client.XAdd(&redis.XAddArgs{
Stream: "tickets",
MaxLen: 0,
MaxLenApprox: 0,
ID: "",
Values: map[string]interface{}{
"whatHappened": string("ticket received"),
"ticketID": int(rand.Intn(100000000)),
"ticketData": string("some ticket data"),
},
}).Err()
stopTime := time.Now().UnixNano() / 1000
log.Printf("生产者用时 %d 毫秒 \n", (stopTime-startTime)/1000)
return err
}
func main() {
log.Println("Publisher started")
redisClient := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%s", "10.50.28.204", "32748"),
Password: "xxxx",
DB: 15,
})
_, err := redisClient.Ping().Result()
if err != nil {
log.Fatal("Unable to connect to Redis", err)
}
log.Println("Connected to Redis server")
for i := 0; i < 3000; i++ {
err = publishTicketReceivedEvent(redisClient)
if err != nil {
log.Fatal(err)
}
}
}
消费者:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/go-redis/redis"
// "github.com/redis/go-redis/v9"
"github.com/rs/xid"
)
//func handleNewTicket(ticketID string, ticketData string) error {
// log.Printf("Handling new ticket id : %s data %s\n", ticketID, ticketData)
// return nil
//}
var ctx = context.Background()
func main() {
log.Println("Consumer started")
redisClient := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%s", "10.50.28.204", "32748"),
Password: "xxxx",
DB: 15,
})
_, err := redisClient.Ping(ctx).Result()
if err != nil {
log.Fatal("Unbale to connect to Redis", err)
}
log.Println("Connected to Redis server")
subject := "tickets"
consumersGroup := "tickets-consumer-group"
err = redisClient.XGroupCreate(ctx, subject, consumersGroup, "0").Err()
if err != nil {
log.Println(err)
}
uniqueID := xid.New().String()
for {
startTime := time.Now().UnixNano() / 1000
entries, err := redisClient.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: consumersGroup,
Consumer: uniqueID,
Streams: []string{subject, ">"},
Count: 2,
Block: 0,
NoAck: false,
}).Result()
if err != nil {
log.Fatal(err)
}
for i := 0; i < len(entries[0].Messages); i++ {
messageID := entries[0].Messages[i].ID
values := entries[0].Messages[i].Values
eventDescription := fmt.Sprintf("%v", values["whatHappened"])
ticketID := fmt.Sprintf("%v", values["ticketID"])
ticketData := fmt.Sprintf("%v", values["ticketData"])
if eventDescription == "ticket received" {
stopTime := time.Now().UnixNano() / 1000
log.Printf("Handling new ticket id : %s data %s 用时 %d 毫秒 \n", ticketID, ticketData, (stopTime-startTime)/1000)
//err := handleNewTicket(ticketID, ticketData,stopTime)
//if err != nil {
// log.Fatal(err)
//}
redisClient.XAck(ctx, subject, consumersGroup, messageID)
}
}
}
}