分布式锁(Redis/Etcd)
大约 2 分钟componentredisetcddistributed lock
概述
dlock
是基于 redsync 和 etcd 构建的分布式锁库,具有以下特点:
- 提供简洁直观的 API 接口
- 支持跨协程/跨服务的互斥锁机制
使用示例
Redis 分布式锁
package main
import (
"context"
"fmt"
"time"
"github.com/go-dev-frame/sponge/pkg/goredis"
"github.com/go-dev-frame/sponge/pkg/dlock"
)
func main() {
redisCli, err := goredis.Init("default:123456@192.168.3.37:6379") // 但个redis实例
// redisCli, err := goredis.InitSentinel(...) // redis 哨兵集群
// clusterRedisCli, err := goredis.InitCluster(...) // redis 集群
if err != nil {
panic(err)
}
defer redisCli.Close()
locker, err := dlock.NewRedisLock(redisCli, "test_lock")
if err != nil {
panic(err)
}
ctx, _ := context.WithTimeout(context.Background(), time.Second*10)
// 示例 1: try to acquire lock, unblock if failed
{
ok, err := locker.TryLock(ctx)
if err != nil {
fmt.Println("failed to TryLock", err)
return
}
if !ok {
fmt.Println("failed to lock")
return
}
defer func() {
if err := locker.Unlock(ctx); err != nil {
fmt.Println("failed to unlock", err)
return
}
}()
// 这里执行需要锁保护的业务逻辑
// ......
}
// 示例 2: lock acquired, block until released, timeout, ctx error
{
if err := locker.Lock(ctx); err != nil {
fmt.Println("failed to lock")
return
}
defer func() {
if err := locker.Unlock(ctx); err != nil {
fmt.Println("failed to unlock", err)
return
}
}()
// 这里执行需要锁保护的业务逻辑
// ......
}
}
Etcd 分布式锁
package main
import (
"context"
"fmt"
"time"
"github.com/go-dev-frame/sponge/pkg/etcdcli"
"github.com/go-dev-frame/sponge/pkg/dlock"
)
func main() {
endpoints := []string{"192.168.3.37:2379"}
cli, err := etcdcli.Init(endpoints, etcdcli.WithConnectTimeout(time.Second*5))
if err!= nil {
panic(err)
}
defer cli.Close()
locker, err := dlock.NewEtcd(cli, "sponge/dlock", 10)
if err != nil {
panic(err)
}
ctx, _ := context.WithTimeout(context.Background(), time.Second*10)
// 示例 1: try to acquire lock, unblock if failed
{
ok, err := locker.TryLock(ctx)
if err != nil {
fmt.Println("failed to TryLock", err)
return
}
if !ok {
fmt.Println("failed to lock")
return
}
defer func() {
if err := locker.Unlock(ctx); err != nil {
fmt.Println("failed to unlock", err)
return
}
}()
// 这里执行需要锁保护的业务逻辑
// ......
}
// 示例 2: lock acquired, block until released, timeout, ctx error
{
if err := locker.Lock(ctx); err != nil {
fmt.Println("failed to lock", err)
return
}
defer func() {
if err := locker.Unlock(ctx); err != nil {
fmt.Println("failed to unlock", err)
return
}
}()
// 这里执行需要锁保护的业务逻辑
// ......
}
}