Redsync 是一个基于 Go 的 Redis 实现的分布式锁库,它使用了 Redis 的 SETNX 和 EXPIRE 命令来实现分布式锁。以下是一个简单的示例,展示了如何在 Go 中使用 Redsync 库来实现分布式锁:
Installation
使用 go get 命令安装 Redsync:
go get github.com/go-redsync/redsync/v4
Usage
接下来是一个使用 Redsync 实现分布式锁的示例代码:
// Package redsync
// @Author zhongxc
// @Date 2023/12/11 15:43:00
// @Desc
package main
import (
"context"
"fmt"
"github.com/go-redsync/redsync/v4"
"github.com/go-redsync/redsync/v4/redis/goredis/v9"
goredislib "github.com/redis/go-redis/v9"
"log"
"time"
)
func main() {
// 创建客户端实例
client := goredislib.NewClient(&goredislib.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
})
defer func(client *goredislib.Client) {
_ = client.Close()
}(client)
// 创建Redsync实例
pool := goredis.NewPool(client)
rs := redsync.New(pool)
// 创建锁,设置默认过期时间为10秒钟
mutexname := "my-global-mutex"
mutex := rs.NewMutex(mutexname, redsync.WithExpiry(10*time.Second))
ctx, cancelFunc := context.WithCancel(context.Background())
defer cancelFunc() // 在函数结束时取消context
// 尝试获取锁
if err := mutex.Lock(); err != nil {
log.Fatalln(err)
}
log.Println("Successfully acquired lock")
// 开启一个goroutine进行自动续期
go func(ctx context.Context) {
defer fmt.Println("Goroutine stopped")
ticker := time.NewTicker(6 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
// 每隔3秒钟(要比锁的过期时间略短),延长锁的过期时间
if _, err := mutex.Extend(); err != nil {
log.Println("锁延期失败", err)
} else {
log.Println("Lock extended")
}
case <-ctx.Done():
return // 如果context被取消,则结束goroutine
}
}
}(ctx)
// 完成需要锁的工作
log.Println("开始处理获取锁后的工作")
time.Sleep(30 * time.Second)
log.Println("业务处理成功")
// 释放锁,以便其他进程或线程可以获得锁
if ok, err := mutex.Unlock(); !ok || err != nil {
log.Fatalln("unlock failed", err)
}
log.Println("Lock released")
// time.Sleep(30 * time.Second)
}
相关文档
https://github.com/go-redsync/redsync
https://pkg.go.dev/github.com/go-redsync/redsync#Mutex