distlock

package
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package distlock 提供分布式锁功能 用于在分布式环境下保证资源的互斥访问

Package distlock 提供分布式锁功能 本文件实现基于 Redis 的分布式锁

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrLockNotHeld 当前未持有锁
	ErrLockNotHeld = errors.New("lock not held")

	// ErrLockAcquireFailed 获取锁失败
	ErrLockAcquireFailed = errors.New("failed to acquire lock")

	// ErrLockTimeout 获取锁超时
	ErrLockTimeout = errors.New("lock acquire timeout")

	// ErrLockAlreadyHeld 锁已被持有(用于 TryLock)
	ErrLockAlreadyHeld = errors.New("lock already held by another client")

	// ErrClientClosed 客户端已关闭
	ErrClientClosed = errors.New("lock client is closed")
)

预定义错误

Functions

This section is empty.

Types

type Config

type Config struct {
	// KeyPrefix 锁键前缀
	// 默认值: "distlock:"
	KeyPrefix string

	// DefaultTTL 锁的默认过期时间
	// 默认值: 30s
	DefaultTTL time.Duration

	// WatchdogEnabled 是否启用看门狗(自动续期)
	// 默认值: true
	WatchdogEnabled bool

	// WatchdogInterval 看门狗续期间隔
	// 默认值: DefaultTTL / 3
	WatchdogInterval time.Duration

	// RetryCount 默认重试次数(用于 Lock 方法)
	// 默认值: 30
	RetryCount int

	// RetryDelay 默认重试间隔
	// 默认值: 100ms
	RetryDelay time.Duration

	// OnLockAcquired 获取锁成功回调
	OnLockAcquired func(key, token string)

	// OnLockReleased 释放锁回调
	OnLockReleased func(key, token string)

	// OnWatchdogError 看门狗续期失败回调
	OnWatchdogError func(key, token string, err error)
}

Config 分布式锁配置

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig 返回默认配置

type Lock

type Lock interface {
	// Key 获取锁的键名
	Key() string

	// Token 获取锁的唯一标识(用于安全释放)
	Token() string

	// TTL 获取锁的剩余生存时间
	TTL(ctx context.Context) (time.Duration, error)

	// Unlock 释放锁
	// 只有持有锁的客户端才能释放锁
	Unlock(ctx context.Context) error

	// Extend 延长锁的过期时间
	// 用于手动续期(通常由看门狗自动处理)
	Extend(ctx context.Context, ttl time.Duration) error
}

Lock 分布式锁接口

type Locker

type Locker interface {
	// TryLock 尝试获取锁(非阻塞)
	// 如果锁被其他客户端持有,立即返回 ErrLockAlreadyHeld
	TryLock(ctx context.Context, key string) (Lock, error)

	// Lock 获取锁(阻塞等待)
	// 如果锁被其他客户端持有,会等待直到获取成功或超时
	Lock(ctx context.Context, key string) (Lock, error)

	// LockWithRetry 获取锁(带重试配置)
	LockWithRetry(ctx context.Context, key string, retryCount int, retryDelay time.Duration) (Lock, error)

	// Close 关闭客户端
	// 会停止所有看门狗协程
	Close() error
}

Locker 分布式锁客户端接口

type Option

type Option func(*Config)

Option 配置选项函数

func WithDefaultTTL

func WithDefaultTTL(ttl time.Duration) Option

WithDefaultTTL 设置默认过期时间

func WithKeyPrefix

func WithKeyPrefix(prefix string) Option

WithKeyPrefix 设置锁键前缀

func WithOnLockAcquired

func WithOnLockAcquired(fn func(key, token string)) Option

WithOnLockAcquired 设置获取锁成功回调

func WithOnLockReleased

func WithOnLockReleased(fn func(key, token string)) Option

WithOnLockReleased 设置释放锁回调

func WithOnWatchdogError

func WithOnWatchdogError(fn func(key, token string, err error)) Option

WithOnWatchdogError 设置看门狗错误回调

func WithRetryCount

func WithRetryCount(count int) Option

WithRetryCount 设置默认重试次数

func WithRetryDelay

func WithRetryDelay(delay time.Duration) Option

WithRetryDelay 设置默认重试间隔

func WithWatchdog

func WithWatchdog(enabled bool) Option

WithWatchdog 设置是否启用看门狗

func WithWatchdogInterval

func WithWatchdogInterval(interval time.Duration) Option

WithWatchdogInterval 设置看门狗续期间隔

type RedisLocker

type RedisLocker struct {
	// contains filtered or unexported fields
}

RedisLocker 基于 Redis 的分布式锁客户端

func NewRedisLocker

func NewRedisLocker(client redis.UniversalClient, opts ...Option) *RedisLocker

NewRedisLocker 创建 Redis 分布式锁客户端 参数:

  • client: Redis 客户端
  • opts: 配置选项

返回:

  • *RedisLocker: 分布式锁客户端

func (*RedisLocker) Close

func (r *RedisLocker) Close() error

Close 关闭客户端 会停止所有看门狗协程,但不会自动释放锁

func (*RedisLocker) Lock

func (r *RedisLocker) Lock(ctx context.Context, key string) (Lock, error)

Lock 获取锁(阻塞等待) 如果锁被其他客户端持有,会等待直到获取成功或超时

参数:

  • ctx: 上下文,可通过 context.WithTimeout 设置超时
  • key: 锁的键名

返回:

  • Lock: 锁对象
  • error: 获取失败或超时时返回错误

使用示例:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

lock, err := locker.Lock(ctx, "my-resource")
if err != nil {
    return err
}
defer lock.Unlock(context.Background())
// 执行业务逻辑

func (*RedisLocker) LockWithRetry

func (r *RedisLocker) LockWithRetry(ctx context.Context, key string, retryCount int, retryDelay time.Duration) (Lock, error)

LockWithRetry 获取锁(带重试配置) 参数:

  • ctx: 上下文
  • key: 锁的键名
  • retryCount: 重试次数
  • retryDelay: 重试间隔

返回:

  • Lock: 锁对象
  • error: 获取失败时返回错误

func (*RedisLocker) Stats

func (r *RedisLocker) Stats() map[string]interface{}

Stats 获取客户端统计信息

func (*RedisLocker) TryLock

func (r *RedisLocker) TryLock(ctx context.Context, key string) (Lock, error)

TryLock 尝试获取锁(非阻塞) 如果锁被其他客户端持有,立即返回 ErrLockAlreadyHeld

参数:

  • ctx: 上下文
  • key: 锁的键名

返回:

  • Lock: 锁对象,获取成功时返回
  • error: 获取失败时返回错误

使用示例:

lock, err := locker.TryLock(ctx, "my-resource")
if err != nil {
    if errors.Is(err, distlock.ErrLockAlreadyHeld) {
        // 锁被其他客户端持有
    }
    return err
}
defer lock.Unlock(ctx)
// 执行业务逻辑

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL