Go Etcd 分布式锁实战

news2024/10/6 0:33:11

1 分布式锁概述

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

  • 基于数据库:通过数据库事务锁例如for update操作
  • 基于缓存中间件:redis分布式锁、etcd分布式锁等
  • 基于ZK临时节点:zookeeper 临时节点实现分布式锁

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

  • 数据库实现不用额外引入新的中间件,减少系统的依赖性和不稳定性,但性能不会太高,且并发量大时,对数据库压力比较大。
  • ZK实现分布式,因为zk满足了CP,能够保证其数据一致性,不会出现加锁成功后又丢失的问题,但相反性能会降低,并且可用性降低 CAP A不是满足的,详细可以自行了解zk细节
  • redis 实现:最大的优点性能高,能保证AP,保证其高可用。但无法保证一致性,因为redis满足的是AP,可能存在某一个时间节点集群数据S-M同步不一致。

2 分布式锁要点

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

  • 锁载体:redis 受用 K-V 键值作为锁载体,ZK使用临时节点作为载体
  • 锁租期:进程持有分布式锁后不能一直占用,如果因为宕机情况造成锁释放失败,就会一直占用,reds 可以设置过期时间,zk临时节点也会自动删除。
  • 其他要求:比如减少惊群效应、可重入机制、公平锁机制,不同的实现方式有的不能完全满足。

分布式锁选择:

  • qps不大的情况下,那种方式都可以
  • 结合目前技术体系,在不引入新的技术中间件情况下解决问题
  • qps并发极高,但容忍极少的数据丢失或者不一致,建议使用redis实现分布式锁
  • 如果业务要求任何情况下都不允许数据丢失,可以使用zk或者etcd实现

3 Etcd 实现机制

  • 锁载体: 使用 k-v 结构实现
  • 锁租期: Etcd 通过lease可以对 kv 设置租约,当租约到期,kv 将失效删除;避免长时间占用锁不释放放。
  • 自动续期: Etcd 可以对租约进行自动续期,通过KeepAlive实现
  • 公平锁: 多个程序同时抢锁时,会根据 Revision 值大小依次获得锁,可以有效避免 “惊群效应”,公平获取。
  • Watch 机制: 监听机制,Watch 机制支持 Watch 某个固定的 key或者目录, key 或目录发生变化,客户端可以收到通知。

4 代码实现

操作步骤:

  1. 初始化客户端
  2. 创建一个session并设置默认租期30s
  3. 获取指定前缀的锁对象
  4. 加锁
  5. 执行业务
  6. 释放锁

代码:

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("释放锁完成")
}

测试结果
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/543971.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql8之前如何实现row_number() over(partition by xxx order by xxx asc/desc)

文章目录 背景问题分析难点解决方案&#xff1a;总结公式多字段作为分组如何处理 背景 最近笔者在进行对广告业务的数据统计时遇到这种情况&#xff0c;业务方嫌弃离线数仓太慢&#xff0c;又无需太高的实时性本该使用即席查询的OLAP去做&#xff0c;但是当前公司调研的OLAP还…

Unity 2022 版本 寻路 NavMesh

首先装包 先给地图 和 阻挡 设置为静态 然后给地上行走的地方 添加组件 可以直接bake 然后会显示蓝色的可行走路径 player 添加插件 然后给角色添加脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class PlayerMove : Mon…

SpringBoot自动配置底层源码解析

1&#xff0c;配置分类 对于一个Spring项目&#xff0c;主要就是有两种配置 一种是类似端口号、数据库地址、用户名密码等一种是各种Bean&#xff0c;比如整合Mybatis需要配置的MapperFactoryBean&#xff0c;比如整合事务需要配置DataSourceTransactionManager SpringBoot中…

Github copilot几个使用技巧,自动补全代码

一、常用快捷键 快捷键含义tab应用提示代码esc拒绝提示代码ctrlenter打开提示面板选用10个意见代码中的一个Alt]切换建议代码Alt ->逐个应用代码 这些快捷键其实就是红色框的功能&#xff0c;也可以通过鼠标点击操作 下面具体介绍一下常用的三个功能&#xff1a; 1. tab自…

Maven——Maven仓库

1.概念 2.远程仓库 3.本地仓库 4.仓库配置和JDK配置 配置远程仓库&#xff1a; <mirror><id>alimaven</id><mirrorOf>central</mirrorOf><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/publ…

EAI(Enterprise Application Integration,企业应用集成)

目录 1.表示集成&#xff08;界面集成&#xff0c;iframe&#xff09; 2.数据集成&#xff08;中间件&#xff0c;数据库上面一层&#xff09; 3.控制集成&#xff08;API&#xff09; 4.业务流程集成 5.企业之间的应用集成 ​最后推荐一个图片转文字网站 最后推荐一个抖音去…

PowerShell if 使用参考

if 参考 与许多其他语言一样&#xff0c;PowerShell 提供了用于在脚本中有条件地执行代码的语句。 其中一个语句是 If 语句。 今天&#xff0c;我们将深入探讨 PowerShell 中最基本的命令之一。 Powershell 下载&#xff0c;参考 PowershellPowershell 相关文档&#xff0c;…

常用在线工具,非常实用,快收藏起来!

作者丨黑蛋 今天给大家介绍一些常用到的在线工具&#xff0c;能方便我们的日常学习&#xff1a; 编码工具&#xff1a; AES加密解密&#xff1a;http://www.jsons.cn/aesencrypt/ DNA编码解码&#xff1a;https://web.expasy.org/translate/ 双16进制编码解码&#xff1a;ht…

素材发布资源下载 OSS存储+用户组打折+下载限速 V1.1.3(one_market)

插件简介 插件用于各类 资源下载站、数字产品下载站、作品模型下载网站、数字市场网站 等 所有插件都使用管理控制台进行管理,方便后续的统一管理。 管理操作使用AJAX交互,站长管理更加高效快捷。让站长体验更加方便、快捷、高效的管理操作 插件管理功能 全局设置 [基本设置]…

[AI图片生成]自己搭建StableDiffusion安装过程

前言 最近尝试玩玩AI图片生成,安装一路坑 出个一路安装成功的记录 开始 找个空间大的盘符,这玩意将来会很占空间.一个模型大约5g左右,你可能还会装很多模型创建个目录,路径不要有中文安装git 下载地址 详细教程 (如果有忽略)下载 Python3.10.0,记得勾选添加到环境变量选项,安…

看板管理解析:如何通过看板提升项目管理效率?

在目前市面上的项目管理工具中&#xff0c;项目看板功能基本上成为了标配。看板作为敏捷的项目管理工具&#xff0c;可以帮助我们将项目工作可视化展现。 项目看板的作用 1&#xff0c;提高团队信息流动性&#xff1a;看板工具可以及时的传递项目工作中的最新讯息&#xff0c;保…

CC++动态内存管理

C&C动态内存管理 C语言动态内存管理 关于C语言动态内存管理实际上就三个函数malloc和calloc以及realloc&#xff0c;更多的是去理解&#xff0c;用C语言去实现数据结构阶段如果细心你就会可以发现&#xff0c;所有的数据结构都是使用动态内存管理的方式&#xff0c;在堆区…

什么是自然语言处理的文本分析?

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是一种人工智能技术&#xff0c;旨在使计算机能够理解、解释和生成自然语言。文本分析是NLP的一个重要领域&#xff0c;它涉及到从文本数据中提取有用信息的过程。本文将详细介绍自然语言处理的…

如何压缩pdf文件的大小?四种方法值得收藏

如何压缩pdf文件的大小&#xff1f;实际上&#xff0c;压缩PDF文件的主要原因是为了减小文件的大小以便于存储、传输和分享。通常情况下&#xff0c;PDF文件包含大量的图像、文本和其他媒体元素&#xff0c;因此它们的文件大小可能会非常大。如果您需要通过电子邮件或网络共享P…

Qt- QSS样式表用法及用例说明

这里写自定义目录标题 QSS样式表用法1.Qt样式表语法2.选择器3.属性列表4.冲突解决5.全局添加QSS QSS样式表用法 整理qss样式表语法知识&#xff0c;方便今后查看。 1.Qt样式表语法 Qt样式表支持各种属性、伪状态和子控件&#xff0c;可以自定义小部件的外观 selector { attr…

这篇文章教你截图怎么翻译

在我们日常生活和工作中&#xff0c;可能会遇到一些需要翻译的文字内容&#xff0c;例如外语文件、国外的路标等。此时&#xff0c;我们也可以选择手动输入这些文字进行翻译&#xff0c;但是这样不仅费时费力&#xff0c;还容易出现翻译错误的情况。相比之下&#xff0c;我认为…

基于三维数字地球的智慧水利防洪数字沙盘解决方案,助力水利工程数字化升级

简介&#xff1a; 水利防洪电子沙盘主要是基于三维 GIS 平台&#xff0c;采用遥感&#xff08;RS&#xff09;、地理信息系统&#xff08;GIS&#xff09;、虚拟现实&#xff08;VR&#xff09;等技术&#xff0c;在三维电子沙盘场景建设的基础上&#xff0c;加入基础地理信息…

腾讯天幕:荣获首届“IPv6技术应用创新大赛”全国总决赛优秀奖

近日&#xff0c;首届“IPv6技术应用创新大赛”全国总决赛圆满落下帷幕。经过层层选拔、激烈角逐&#xff0c;腾讯参赛项目“IPv6时代下的腾讯天幕安全算力算法PaaS”凭借旁路部署、高阻断率、海量流量实时监控及处理、大数据实时处理分析、联动开放等核心优势&#xff0c;从15…

Java面试知识点(全)- Java并发-多线程JUC二-原子类/锁

Java面试知识点(全) 导航&#xff1a; https://nanxiang.blog.csdn.net/article/details/130640392 注&#xff1a;随时更新 JUC原子类 什么是CAS CAS的全称为Compare-And-Swap&#xff0c;直译就是对比交换。是一条CPU的原子指令&#xff0c;其作用是让CPU先进行比较两个值…

人体传感器SR501控制继电器

人体传感器SR501 原理 红外热释电检测移动人体 缺点 只能识别移动人体&#xff08;静止的不行&#xff09; 容易误判 正面 背面电路 跳线 H&#xff1a;触发周期可重复触发&#xff0c;一般选用此 L&#xff1a;不可重复触发&#xff0c;关掉之后才会重新触发 封锁周期 …