Documentation
¶
Overview ¶
Package dlock 提供 Genesis 的分布式锁组件。
`dlock` 的定位是为常见的“跨实例互斥”场景提供一层克制、统一的锁接口, 当前支持 Redis 和 Etcd 两种后端。调用方通过 `Locker` 使用阻塞式 `Lock`、 非阻塞式 `TryLock`、显式 `Unlock` 和 `Close`,不需要直接处理 Redis 的 token 校验或 Etcd 的 session / mutex 细节。
这个组件的核心目标不是抽象出一个“万能锁框架”,而是把最常见、最稳定的 分布式锁能力收敛成少量接口,并把几个容易出错的边界收紧:
- Redis 使用 token + Lua 脚本,避免误删别人的锁。
- Redis 和 Etcd 都会在锁持有期间自动续期。
- `Close()` 会停止续期,并尽力释放当前 `Locker` 已持有的锁。
- 同一个 `Locker` 不允许本地重入同一个 key。
`dlock` 不负责可重入锁、读写锁、公平锁、锁诊断平台或死锁检测。它更适合 任务竞选、资源互斥、短事务串行化这类“需要一把简单分布式锁”的场景。
需要注意的是,Redis 与 Etcd 并不是完全等价的协议实现。尤其在 TTL 语义上, Etcd 依赖 lease,精度为秒级,因此 `DefaultTTL` 和 `WithTTL(...)` 都要求 至少 1 秒且必须是整秒;Redis 则直接使用原生 `time.Duration`。
Index ¶
Constants ¶
This section is empty.
Variables ¶
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") // ErrInvalidTTL TTL 配置非法 ErrInvalidTTL = xerrors.New("dlock: invalid ttl") )
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。
需要注意:
- Redis 支持原生 time.Duration 精度
- Etcd 的 TTL 基于 lease,必须至少 1 秒且为整秒,否则返回 ErrInvalidTTL
使用示例:
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 的持有状态。
// 它会停止自动续期,并尽力释放当前 Locker 已持有的锁。
// 底层 Redis / Etcd 连接器仍由调用方负责关闭。
Close() error
}
Locker 定义了分布式锁的核心行为
type Option ¶
type Option func(*options)
Option DLock 组件初始化选项函数
func WithEtcdConnector ¶
func WithEtcdConnector(conn connector.EtcdConnector) Option
WithEtcdConnector 注入 Etcd 连接器
func WithLogger ¶
WithLogger 注入日志记录器 组件会自动添加 component=dlock 字段
func WithRedisConnector ¶
func WithRedisConnector(conn connector.RedisConnector) Option
WithRedisConnector 注入 Redis 连接器