dlock

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Feb 13, 2026 License: MIT Imports: 11 Imported by: 0

README

dlock - 分布式锁组件

dlock 是 Genesis 的分布式锁组件,支持 Redis 和 Etcd 后端。

特性

  • 后端无关:支持 Redis、Etcd,通过配置灵活切换
  • 自动续期:Redis Watchdog / Etcd Session KeepAlive
  • 防误删:通过 token 机制确保只有锁持有者才能释放

目录结构

dlock/
├── README.md        # 组件文档
├── dlock.go         # 公开 API: New()
├── types.go         # Locker, Config, DriverType
├── options.go       # Option, WithLogger, With*Connector
├── lock_options.go  # LockOption, WithTTL
├── errors.go        # 标准错误定义
├── redis.go         # Redis 后端
└── etcd.go          # Etcd 后端

快速开始

Redis
redisConn, _ := connector.NewRedis(&cfg.Redis, connector.WithLogger(logger))
defer redisConn.Close()

locker, _ := dlock.New(&dlock.Config{
    Driver:        dlock.DriverRedis,
    Prefix:        "myapp:lock:",
    DefaultTTL:    10 * time.Second,
    RetryInterval: 100 * time.Millisecond,
}, dlock.WithRedisConnector(redisConn), dlock.WithLogger(logger))

ctx := context.Background()
if err := locker.Lock(ctx, "resource-key"); err != nil {
    return err
}
defer locker.Unlock(ctx, "resource-key")
Etcd
etcdConn, _ := connector.NewEtcd(&cfg.Etcd, connector.WithLogger(logger))
defer etcdConn.Close()

locker, _ := dlock.New(&dlock.Config{
    Driver:     dlock.DriverEtcd,
    Prefix:     "myapp:lock:",
    DefaultTTL: 30 * time.Second,
}, dlock.WithEtcdConnector(etcdConn), dlock.WithLogger(logger))

核心接口

Locker
type Locker interface {
    Lock(ctx context.Context, key string, opts ...LockOption) error
    TryLock(ctx context.Context, key string, opts ...LockOption) (bool, error)
    Unlock(ctx context.Context, key string) error
}
Config
type Config struct {
    Driver        DriverType   // redis | etcd
    Prefix        string       // 锁 Key 前缀,如 "myapp:lock:"
    DefaultTTL    time.Duration // 默认锁超时时间
    RetryInterval time.Duration // 加锁重试间隔
}

应用场景

任务竞选
acquired, _ := locker.TryLock(ctx, "scheduled-task:cleanup")
if acquired {
    defer locker.Unlock(ctx, "scheduled-task:cleanup")
    runCleanup()
}
库存扣减
locker.Lock(ctx, fmt.Sprintf("inventory:%d", productID),
    dlock.WithTTL(30*time.Second))
defer locker.Unlock(ctx, fmt.Sprintf("inventory:%d", productID))

可观测性

通过 WithLogger 注入日志器,自动添加 component=dlock 字段。

工厂函数

func New(cfg *Config, opts ...Option) (Locker, error)

选项:WithRedisConnectorWithEtcdConnectorWithLogger

标准错误

var (
    ErrConfigNil       = xerrors.New("dlock: config is nil")
    ErrConnectorNil    = xerrors.New("dlock: connector is nil")
    ErrLockNotHeld     = xerrors.New("dlock: lock not held")
    ErrLockAlreadyHeld = xerrors.New("dlock: lock already held locally")
    ErrOwnershipLost   = xerrors.New("dlock: ownership lost")
)

完整示例

参考 examples/dlock/main.go

Documentation

Overview

Package dlock 提供分布式锁组件,支持 Redis 和 Etcd 后端。

特性:

  • 统一的 Locker 接口,屏蔽后端差异

  • 阻塞式 Lock / 非阻塞 TryLock

  • 自动续期(Redis Watchdog / Etcd Session KeepAlive)

  • 防误删机制(token 校验)

    redisConn, _ := connector.NewRedis(&cfg.Redis, connector.WithLogger(logger)) locker, _ := dlock.New(&dlock.Config{ Driver: dlock.DriverRedis, Prefix: "myapp:lock:", }, dlock.WithRedisConnector(redisConn), dlock.WithLogger(logger))

    if err := locker.Lock(ctx, "resource-key"); err != nil { return err } defer locker.Unlock(ctx, "resource-key")

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrConfigNil 配置为空
	ErrConfigNil = xerrors.New("dlock: config is nil")

	// ErrConnectorNil 连接器为空
	ErrConnectorNil = xerrors.New("dlock: connector is nil")

	// ErrLockNotHeld 锁未持有
	ErrLockNotHeld = xerrors.New("dlock: lock not held")

	// ErrLockAlreadyHeld 锁已在本地持有
	ErrLockAlreadyHeld = xerrors.New("dlock: lock already held locally")

	// ErrOwnershipLost 锁所有权丢失
	ErrOwnershipLost = xerrors.New("dlock: ownership lost")
)

Functions

This section is empty.

Types

type Config

type Config struct {
	// Driver 选择使用的后端 (redis | etcd)
	Driver DriverType `json:"driver" yaml:"driver"`

	// Prefix 锁 Key 的全局前缀,例如 "dlock:"
	Prefix string `json:"prefix" yaml:"prefix"`

	// DefaultTTL 默认锁超时时间
	// Redis 会启动 Watchdog 自动续期;Etcd 使用 Session KeepAlive 自动续期。
	DefaultTTL time.Duration `json:"default_ttl" yaml:"default_ttl"`

	// RetryInterval 加锁重试间隔 (仅 Lock 模式有效)
	RetryInterval time.Duration `json:"retry_interval" yaml:"retry_interval"`
}

Config 组件静态配置

type DriverType

type DriverType string

DriverType 定义支持的后端类型

const (
	DriverRedis DriverType = "redis"
	DriverEtcd  DriverType = "etcd"
)

type LockOption

type LockOption func(*lockOptions)

LockOption Lock 操作的选项函数

func WithTTL

func WithTTL(d time.Duration) LockOption

WithTTL 设置锁的 TTL(超时时间) 用于覆盖配置中的 DefaultTTL

使用示例:

locker.Lock(ctx, "key", dlock.WithTTL(10*time.Second))

type Locker

type Locker interface {
	// Lock 阻塞式加锁
	// 成功返回 nil,失败返回错误
	// 如果上下文取消,返回 context.Canceled 或 context.DeadlineExceeded
	//
	// opts 支持的选项:
	//   - WithTTL(duration): 设置锁的超时时间
	Lock(ctx context.Context, key string, opts ...LockOption) error

	// TryLock 非阻塞式尝试加锁
	// 成功获取锁返回 true, nil
	// 锁已被占用返回 false, nil
	// 发生错误返回 false, err
	//
	// opts 支持的选项:
	//   - WithTTL(duration): 设置锁的超时时间
	TryLock(ctx context.Context, key string, opts ...LockOption) (bool, error)

	// Unlock 释放锁
	// 只有锁的持有者才能成功释放
	Unlock(ctx context.Context, key string) error

	// Close 关闭 Locker,释放底层资源
	// 对于 Etcd 会关闭 session,对于 Redis 是 no-op
	Close() error
}

Locker 定义了分布式锁的核心行为

func New

func New(cfg *Config, opts ...Option) (Locker, error)

New 创建分布式锁组件(配置驱动)

通过 cfg.Driver 选择后端,连接器通过 Option 注入:

  • DriverRedis: WithRedisConnector
  • DriverEtcd: WithEtcdConnector

type Option

type Option func(*options)

Option DLock 组件初始化选项函数

func WithEtcdConnector

func WithEtcdConnector(conn connector.EtcdConnector) Option

WithEtcdConnector 注入 Etcd 连接器

func WithLogger

func WithLogger(l clog.Logger) Option

WithLogger 注入日志记录器 组件会自动添加 component=dlock 字段

func WithRedisConnector

func WithRedisConnector(conn connector.RedisConnector) Option

WithRedisConnector 注入 Redis 连接器

Jump to

Keyboard shortcuts

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