Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money

A preface.

Redis can be used to publish and subscribe messages instead of Kafka in the case of small data volumes. Kafka performs well in scenarios with large data volumes, but for such small scenarios, not only does it cost more to operate and maintain, but it doesn’t require much performance.

However, another disadvantage of using Redis is that messages do not accumulate and will be lost if the consumer node does not consume messages. Therefore, it is necessary to evaluate the current scenario to choose the appropriate architecture.

Go-redis is used here to implement redis publish and subscribe.

Ii. Official documents

The official documentation has a more complete example:

pubsub := rdb.Subscribe(ctx, "mychannel1")

// Wait for confirmation that subscription is created before publishing anything.
_, err := pubsub.Receive(ctx)
iferr ! =nil {
	panic(err)
}

// Go channel which receives messages.
ch := pubsub.Channel()

// Publish a message.
err = rdb.Publish(ctx, "mychannel1"."hello").Err()
iferr ! =nil {
	panic(err)
}

time.AfterFunc(time.Second, func(a) {
	// When pubsub is closed channel is closed too.
	_ = pubsub.Close()
})

// Consume messages.
for msg := range ch {
	fmt.Println(msg.Channel, msg.Payload)
}
Copy the code

Three. Code implementation

The implementation code is explained step by step.

1. Connect to redis

func redisConnect(a) (rdb *redis.Client) {

	var (
		redisServer string
		port        string
		password    string
	)

	redisServer = os.Getenv("RedisUrl")
	port = os.Getenv("RedisPort")
	password = os.Getenv("RedisPass")

	rdb = redis.NewClient(&redis.Options{
		Addr:     redisServer + ":" + port,
		Password: password,
		DB:       0.// use default DB
	})

	return
}
Copy the code

2. Post the news

func pubMessage(channel, msg string) {
	rdb := redisConnect()
	rdb.Publish(context.Background(), channel, msg)
}
Copy the code

3. Subscribe to messages

func subMessage(channel string) {
	rdb := redisConnect()
	pubsub := rdb.Subscribe(context.Background(), channel)
	_, err := pubsub.Receive(context.Background())
	iferr ! =nil {
		panic(err)
	}

	ch := pubsub.Channel()
	for msg := range ch {
		fmt.Println(msg.Channel, msg.Payload)
	}
}
Copy the code

4. Complete case

There is a publish node and a subscribe node to realize simple publish and subscribe.

1. Message publishing node

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/go-redis/redis/v8"
)

func redisConnect(a) (rdb *redis.Client) {

	var (
		redisServer string
		port        string
		password    string
	)

	redisServer = os.Getenv("RedisUrl")
	port = os.Getenv("RedisPort")
	password = os.Getenv("RedisPass")

	rdb = redis.NewClient(&redis.Options{
		Addr:     redisServer + ":" + port,
		Password: password,
		DB:       0.// use default DB
	})

	return
}

func pubMessage(channel, msg string) {
	rdb := redisConnect()
	rdb.Publish(context.Background(), channel, msg)
}

func main(a) {
	channel := "hello"
	msgList := []string{"hello"."world"}

  // Two messages are sent here
	for _, msg := range msgList {
		pubMessage(channel, msg)
		fmt.Printf("%s has been sent to %s\n", msg, channel)
	}
}
Copy the code

2. Message subscription node

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/go-redis/redis/v8"
)

func redisConnect(a) (rdb *redis.Client) {

	var (
		redisServer string
		port        string
		password    string
	)

	redisServer = os.Getenv("RedisUrl")
	port = os.Getenv("RedisPort")
	password = os.Getenv("RedisPass")

	rdb = redis.NewClient(&redis.Options{
		Addr:     redisServer + ":" + port,
		Password: password,
		DB:       0.// use default DB
	})

	return
}

func subMessage(channel string) {
	rdb := redisConnect()
	pubsub := rdb.Subscribe(context.Background(), channel)
	_, err := pubsub.Receive(context.Background())
	iferr ! =nil {
		panic(err)
	}

	ch := pubsub.Channel()
	for msg := range ch {
		fmt.Println(msg.Channel, msg.Payload)
	}
}

func main(a) {
    channel := "hello"
    subMessage(channel)
}

Copy the code

Five. Operation results

1. Message publishing node output

2. Message subscription node output

Vi. Original blog

  • Publish and subscribe to Go-Redis