在Go语言中,可以使用分布式锁来解决多个进程或节点同时对同一资源进行修改的问题。常见的分布式锁实现方式包括基于ZooKeeper、Redis等分布式存储系统的实现。
以下是使用Redis实现分布式锁的示例代码:
package main
import (
"fmt"
"github.com/go-redis/redis"
"time"
)
var redisClient *redis.Client
func init() {
// 初始化 Redis 客户端
redisClient = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
}
// 获取分布式锁
func acquireLock(lockKey string, timeout time.Duration) (bool, error) {
for {
// 在 Redis 中设置一个带有过期时间的键值对作为锁
success, err := redisClient.SetNX(lockKey, time.Now().Unix(), timeout).Result()
if err != nil {
return false, err
}
if success {
return true, nil
}
time.Sleep(100 * time.Millisecond)
}
}
// 释放分布式锁
func releaseLock(lockKey string) error {
_, err := redisClient.Del(lockKey).Result()
return err
}
func main() {
lockKey := "my_lock_key"
// 尝试获取分布式锁,超时时间为10秒钟
locked, err := acquireLock(lockKey, 10*time.Second)
if err != nil {
fmt.Println("Failed to acquire lock:", err)
return
}
if !locked {
fmt.Println("Failed to acquire lock")
return
}
defer releaseLock(lockKey)
// 在这里执行需要加锁的代码
fmt.Println("Got the lock!")
}
在上述代码中,我们使用go-redis库来连接Redis数据库,并实现了acquireLock和releaseLock两个函数来获取和释放分布式锁。其中,acquireLock函数会在Redis中设置一个带有过期时间的键值对作为锁,并通过循环判断当前是否能够获取到该锁;而releaseLock函数则是通过删除该键值对来释放锁。
需要注意的是,在使用分布式锁时,应当避免死锁和多次解除同一把锁的情况。此外,在设置过期时间时应根据业务需要合理设置,以兼顾程序性能和数据一致性。




