golang 每日一庫之 bsm-redislock

bsm/redislock 是一個用於 在 Go 語言中實現基於 Redis 的分佈式鎖(distributed lock) 的開源庫,由 bsm 組織開發和維護。

它實現了基於 Redis 的 SET NX PX 命令模式的分佈式鎖,兼容 Redlock 算法的核心思想,但更簡單和輕量。

簡介

安裝方法

go get github.com/bsm/redislock

示例

import (
  "context"
  "fmt"
  "log"
  "time"
  "github.com/bsm/redislock"
  "github.com/redis/go-redis/v9"
)
func main() {
	// Connect to redis.
	client := redis.NewClient(&redis.Options{
		Network:	"tcp",
		Addr:		"127.0.0.1:6379",
	})
	defer client.Close()
	// Create a new lock client.
	locker := redislock.New(client)
	ctx := context.Background()
	// Try to obtain lock.
	lock, err := locker.Obtain(ctx, "my-key", 100*time.Millisecond, nil)
	if err == redislock.ErrNotObtained {
		fmt.Println("Could not obtain lock!")
	} else if err != nil {
		log.Fatalln(err)
	}
	// Don't forget to defer Release.
	defer lock.Release(ctx)
	fmt.Println("I have a lock!")
	// Sleep and check the remaining TTL.
	time.Sleep(50 * time.Millisecond)
	if ttl, err := lock.TTL(ctx); err != nil {
		log.Fatalln(err)
	} else if ttl > 0 {
		fmt.Println("Yay, I still have my lock!")
	}
	// Extend my lock.
	if err := lock.Refresh(ctx, 100*time.Millisecond, nil); err != nil {
		log.Fatalln(err)
	}
	// Sleep a little longer, then check.
	time.Sleep(100 * time.Millisecond)
	if ttl, err := lock.TTL(ctx); err != nil {
		log.Fatalln(err)
	} else if ttl == 0 {
		fmt.Println("Now, my lock has expired!")
	}
}

支持鎖續約

你可以對鎖進行續期以延長其有效期:

err := lock.Refresh(ctx, 10*time.Second, nil)

配置選項

示例:

opts := &redislock.Options{
    RetryStrategy: redislock.LinearBackoff(500 * time.Millisecond),
}
lock, err := locker.Obtain(ctx, "my-key", 10*time.Second, opts)

鎖是否仍然有效

ok, err := lock.Valid(ctx)

如果 ok == false,表示鎖已經過期或被其他客戶端釋放 / 搶佔。

缺點

標題:golang 每日一庫之 bsm/redislock
作者:mooncakeee
地址:http://blog.dd95828.com/articles/2025/05/23/1747978638082.html
聯繫:scotttu@163.com

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/BhFlVt0gorfnfF84aW0L6g