Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go Etcd分布式锁

Go语言使用Etcd实现分布式锁

作者:small_to_large

etcd是近几年比较火热的一个开源的、分布式的键值对数据存储系统,本文将介绍如何利用Etcd实现分布式锁,感兴趣的小伙伴可以跟随小编一起了解一下

1 分布式锁概述

谈到分布式锁,必然是因为单机锁无法满足要求,在现阶段微服务多实例部署的情况下,单机语言级别的锁,无法满足并发互斥资源的安全访问。常见的单机锁如Java的jvm锁Locksynchronized,golang的Mutex等 对于分布式锁有很多种实现方式,常见的有以下几种:

每种方式实现的分布式锁各有优缺点简单介绍一下:

2 分布式锁要点

实现分布式锁需要满足一下几点:

分布式锁选择:

3 Etcd 实现机制

4 代码实现

操作步骤:

代码:

package main
import (
	"context"
	clientv3 "go.etcd.io/etcd/client/v3"
	"go.etcd.io/etcd/client/v3/concurrency"
	"log"
	"time"
)
func main() {
	// 初始化客户端
	log.Println("客户端初始化")
	client, err := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}, DialTimeout: time.Second * 3})
	if err != nil {
		log.Fatalf("客户端初始化失败:%v\n", err)
	}
	// 创建一个session并设置默认租期30s,即锁默认超过30s会自动释放(内部会自动续期Etcd KeepAlive)
	log.Println("Session初始化")
	session, err := concurrency.NewSession(client, concurrency.WithTTL(30))
	if err != nil {
		log.Fatalf("Session初始化失败:%v\n", err)
		return
	}
	defer func(session *concurrency.Session) {
		err := session.Close()
		if err != nil {
			log.Fatalf("Session关闭失败:%v\n", err)
		}
	}(session)
	// 获取指定前缀的锁对象
	mutex := concurrency.NewMutex(session, "my-lock")
	// 加锁默认等待3s
	log.Println("TryLock加锁失败不会等待")
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
	defer cancel()
	err = mutex.TryLock(ctx)
	if err != nil {
		log.Fatalf("加锁失败立即返回:%v\n", err)
		return
	}
	//log.Println("加锁最多等待3s")
	//ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
	//defer cancel()
	//err = mutex.Lock(ctx)
	//if err != nil {
	//	log.Fatalf("加锁失败:%v\n", err)
	//	return
	//}
	// Exe biz
	log.Println("加锁成功开始执行业务")
	for i := 1; i <= 10; i++ {
		time.Sleep(time.Second)
		log.Printf("执行 %%%d ...", i*10)
	}
	// 释放锁
	err = mutex.Unlock(context.TODO())
	if err != nil {
		log.Fatalf("释放锁失败:%v\n", err)
		return
	}
	log.Println("释放锁完成")
}

测试结果 

到此这篇关于Go语言使用Etcd实现分布式锁的文章就介绍到这了,更多相关Go Etcd分布式锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文