Redsync 多 Redis 实例使用 demo

完整代码传送门

package main

import (
	"context"
	"fmt"
	"net/http"
	"redis-distributed-lock/redis_client"
	"strconv"

	"github.com/go-redsync/redsync/v4"
	"github.com/go-redsync/redsync/v4/redis/goredis/v9"
)

const port = 9981

func main() {
	http.HandleFunc("/inventory/sale", sale)
	fmt.Printf("service start, port: %v\n", port)
	if err := http.ListenAndServe(fmt.Sprintf(":%v", port), nil); err != nil {
		panic(err)
	}
}

const mutexName = "redlock"

func sale(w http.ResponseWriter, r *http.Request) {
	pool1 := goredis.NewPool(redis_client.NewClientWithAddr("localhost:6380"))
	pool2 := goredis.NewPool(redis_client.NewClientWithAddr("localhost:6381"))
	pool3 := goredis.NewPool(redis_client.NewClientWithAddr("localhost:6382"))
	rs := redsync.New(pool1, pool2, pool3)
	mutex := rs.NewMutex(mutexName)
	if err := mutex.Lock(); err != nil {
		fmt.Printf("lock failed, err: %v\n", err)
	}

	reduceInventory()

	if ok, err := mutex.Unlock(); !ok || err != nil {
		fmt.Printf("unlock failed, err: %v\n", err)
	}
}

const inventoryKey = "inventory"

func reduceInventory() (string, error) {
	client := redis_client.NewClient()
	val, err := client.Get(context.Background(), inventoryKey).Result()
	if err != nil {
		fmt.Printf("redis get failed, err: %v, key: %v\n", err, inventoryKey)
		return "", err
	}

	inventory, err := strconv.ParseInt(val, 10, 64)
	if err != nil {
		fmt.Printf("parse int failed, err: %v, val: %v\n", err, inventory)
		return "", err
	}

	var msg string
	if inventory > 0 {
		if err := client.Set(context.Background(), inventoryKey, inventory-1, 0).Err(); err != nil {
			fmt.Printf("redis set failed, err: %v, key: %v\n", err, inventoryKey)
			return "", err
		}
		msg = fmt.Sprintf("inventory: %v, port: %v", inventory-1, port)
	} else {
		msg = fmt.Sprintf("product slod out, port: %v", port)
	}
	fmt.Println(msg)
	return msg, nil
}

你可能感兴趣的:(随笔,redis)