当前位置: 首页 > news >正文

Go Etcd

基本操作

go get go.etcd.io/etcd/client/v3# 此处使用的 版本是:
# go.etcd.io/etcd/client/v3 v3.5.8

这里使用的是 "go.etcd.io/etcd/client/v3" 而不是 "go.etcd.io/etcd/clientv3"
我们不使用 etcd/clientv3,因为它与grpc 最新版本不兼容,官方最新推荐的方式 etcd/client/v3

package mainimport ("context""fmt""log""time"clientv3 "go.etcd.io/etcd/client/v3"
)func main() {client, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {log.Fatalln(err)}ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()// PUT = add + editkey := "/ns/service" // key 的位置在 /ns/ 目录下的 名为 service 文件 中value := "127.0.0.1:80001"_, err = client.Put(ctx, key, value)if err != nil {log.Printf("etcd put error,%v\n", err)return}// GETgetResponse, err := client.Get(ctx, key)if err != nil {log.Printf("etcd GET error,%v\n", err)return}for _, kv := range getResponse.Kvs {fmt.Printf("Key:%s ===> Val:%s \n", kv.Key, kv.Value)}// DEL_, err = client.Delete(ctx, key)if err != nil {// 处理错误log.Printf("etcd GET error,%v\n", err)return}
}

监听

键的变化

如果值一直没有变化,程序不会退出,而是一直等待。这是因为Watch()方法是一个阻塞方法,会一直等待etcd中指定键的值发生变化或者超时。
如果没有设置超时时间,程序将一直等待,直到键值对发生变化或者程序被强制退出。

如果需要设置超时时间,可以使用context.WithTimeout()方法创建一个带有超时时间的上下文对象,例如:

	key := "/ns/service" // key 的位置在 /ns/ 目录下的 名为 service 文件 中// 发布者go func() {for {time.Sleep(time// 使用cli.Txn()方法创建了一个事务txn := client.Txn(context.Background())// 事务包含了一个条件判断和两个操作:// 条件判断使用 clientv3.Compare() 方法,判断键值对的值是否等于"old_value",// 如果满足条件,则执行clientv3.OpPut()方法,将键值对的值修改为"new_value",// 否则执行clientv3.OpGet()方法,读取键值对的值。txn.If(clientv3.Compare(clientv3.Value("/wtt/key"), "=", "value")).Then(clientv3.OpPut("/wtt/key", "new_value")).Else(clientv3.OpGet("/wtt/key"))// 最后,使用txn.Commit()方法提交事务,如果事务执行成功,则返回resp.Succeeded为true,否则为false。resp, err := txn.Commit()if err != nil {fmt.Println(err)return}if resp.Succeeded {fmt.Println("事务执行成功")} else {fmt.Println("事务执行失败")}.Second * 1)_, err = client.Put(context.Background(), key, "value")if err != nil {log.Printf("etcd put error,%v\n", err)return} else {fmt.Println("have change")}}}()// 订阅者rch := client.Watch(context.Background(), key)for wresp := range rch {for _, ev := range wresp.Events {fmt.Printf("%s %q : %q\n", ev.Type, ev.Kv.Key, ev.Kv.Value)}}

**注意: **

需要注意的是,如果Watch()方法返回错误,例如etcd server连接失败或者上下文对象超时,
程序也会退出。因此,在使用Watch()方法时,需要处理可能出现的错误,以避免程序异常退出

租约

etcd的租约是etcd中一种重要的机制,用于管理键值对的生命周期。
在etcd中,每个键值对都可以关联一个租约,租约可以设置一个过期时间,当租约过期时,etcd会自动删除该键值对。

租约的作用类似于一个定时器,当租约到期时,etcd会自动删除与该租约关联的键值对。租约可以用于实现一些高级功能,例如:

  • 实现分布式锁:使用租约来实现分布式锁,当一个客户端获取锁时,可以创建一个带有租约的键值对,当锁被释放时,租约到期,etcd会自动删除该键值对,从而释放锁。
  • 实现健康检查:使用租约来实现健康检查,当一个服务启动时,可以创建一个带有租约的键值对,当服务停止时,租约到期,etcd会自动删除该键值对,从而通知其他服务该服务已经停止。
  • 实现自动续租:使用租约来实现自动续租,当一个客户端获取租约时,可以定期向etcd发送心跳,从而保持租约的有效性,避免租约过期导致键值对被删除。
	client, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {log.Fatalln(err)}// 创建租约leaseResp, err := client.Grant(context.Background(), 30)if err != nil {fmt.Println(err)return}// 绑定租约到键_, err = client.Put(context.Background(), "/wtt/who", "whero", clientv3.WithLease(leaseResp.ID))if err != nil {fmt.Println(err)return} else {fmt.Println("绑定租约到键 成功")}time.Sleep(time.Second * 10)// 续约租约 (相当于 给 绑定租约 的 键 重新绑定 租约)ch, err := client.KeepAlive(context.Background(), leaseResp.ID)if err != nil {fmt.Println(err)return}ka, ok := <-chif ok {fmt.Println("ttl:", ka.TTL)}// 撤销租约/*当租约被撤销时,etcd会自动删除与该租约关联的键值对。需要注意的是,撤销租约是一个异步操作,etcd会在后台删除与该租约关联的键值对,因此,在撤销租约后,键值对可能不会立即被删除,需要等待一段时间才能生效。*/_, err = client.Revoke(context.Background(), leaseResp.ID)if err != nil {fmt.Println(err)return} else {fmt.Println("撤销租约 成功")}

事务

etcd的事务是指一组操作,这些操作要么全部执行成功,要么全部执行失败,保证了数据的一致性和可靠性。
etcd的事务支持多个操作,包括读取、写入、修改和删除等操作,可以在一个事务中同时执行多个操作,
从而避免了多个操作之间的竞态条件和数据不一致的问题。

	client, err := clientv3.New(clientv3.Config{Endpoints:   []string{"127.0.0.1:2379"},DialTimeout: 5 * time.Second,})if err != nil {log.Fatalln(err)}_, err = client.Put(context.Background(), "/wtt/key", "value")if err != nil {log.Printf("etcd put error,%v\n", err)return}// 使用cli.Txn(etcd的分布式锁是一种基于etcd实现的分布式锁,可以用于多个进程或多台机器之间的协调。etcd的分布式锁使用了etcd的事务操作和租约机制,可以保证锁的正确性和高可用性。)方法创建了一个事务txn := client.Txn(context.Background())// 事务包含了一个条件判断和两个操作:// 条件判断使用 clientv3.Compare() 方法,判断键值对的值是否等于"old_value",// 如果满足条件,则执行clientv3.OpPut()方法,将键值对的值修改为"new_value",// 否则执行clientv3.OpGet()方法,读取键值对的值。txn.If(clientv3.Compare(clientv3.Value("/wtt/key"), "=", "value")).Then(clientv3.OpPut("/wtt/key", "new_value")).Else(clientv3.OpGet("/wtt/key"))// 最后,使用txn.Commit()方法提交事务,如果事务执行成功,则返回resp.Succeeded为true,否则为false。resp, err := txn.Commit()if err != nil {fmt.Println(err)return}if resp.Succeeded {fmt.Println("事务执行成功")} else {fmt.Println("事务执行失败")}

需要注意的是,etcd的事务是原子性的,即要么全部执行成功,要么全部执行失败,不支持部分执行成功的情况。
因此,在使用etcd的事务时,需要仔细考虑每个操作的顺序和条件,避免出现竞态条件和数据不一致的问题。

分布式

分布式锁

etcd的分布式锁是一种基于etcd实现的分布式锁,可以用于 多个进程 或 多台机器 之间的协调。
etcd的分布式锁使用了etcd的 事务操作 和 租约机制,可以保证锁的正确性和高可用性。

package mainimport ("context""fmt""time"clientv3 "go.etcd.io/etcd/client/v3""go.etcd.io/etcd/client/v3/concurrency"
)func main() {// 创建etcd客户端client, err := clientv3.New(clientv3.Config{Endpoints:   []string{"localhost:2379"},DialTimeout: 5 * time.Second,})if err != nil {panic(err)}defer client.Close()go func() {time.Sleep(time.Second * 2)fmt.Println("son start")// 创建一个sessionsession, err := concurrency.NewSession(client)if err != nil {panic(err)}defer session.Close()// 创建一个锁mutex := concurrency.NewMutex(session, "/my-lock")// 加锁err = mutex.Lock(context.Background())if err != nil {panic(err)}fmt.Println("son lock acquired")// 执行业务逻辑time.Sleep(5 * time.Second)// 解锁err = mutex.Unlock(context.Background())if err != nil {panic(err)}fmt.Println("son lock released")}()// 创建一个sessionsession, err := concurrency.NewSession(client)if err != nil {panic(err)}defer session.Close()// 创建一个锁mutex := concurrency.NewMutex(session, "/my-lock")// 加锁err = mutex.Lock(context.Background())if err != nil {panic(err)}fmt.Println("dad lock acquired")// 执行业务逻辑time.Sleep(5 * time.Second)// 解锁err = mutex.Unlock(context.Background())if err != nil {panic(err)}fmt.Println("dad lock released")time.Sleep(time.Hour)
}/*
输出:dad lock acquiredson startdad lock releasedson lock acquiredson lock released
*/

分布式事务

分布式事务是指在分布式系统中,多个节点之间进行的事务操作。
在分布式系统中,不同的节点可能位于不同的物理机器上,它们之间通过网络进行通信。
由于网络通信的不确定性和不可靠性,分布式事务的实现比较复杂。

分布式事务需要满足ACID原则,即原子性、一致性、隔离性和持久性。
其中,原子性指事务是一个不可分割的操作序列,要么全部执行成功,要么全部执行失败;
一致性指事务执行前后,数据库的状态必须保持一致;
隔离性指多个事务之间应该相互隔离,互不干扰;
持久性指事务执行成功后,对数据库的修改应该永久保存。

常见的分布式事务实现方式包括两阶段提交三阶段提交
两阶段提交是指在分布式系统中,事务的提交分为两个阶段,第一个阶段是准备阶段,第二个阶段是提交阶段
三阶段提交是在两阶段提交的基础上,增加了一个预提交阶段,用于解决两阶段提交中的 阻塞问题

集群管理

相关文章:

Go Etcd

基本操作 go get go.etcd.io/etcd/client/v3# 此处使用的 版本是&#xff1a; # go.etcd.io/etcd/client/v3 v3.5.8这里使用的是 "go.etcd.io/etcd/client/v3" 而不是 "go.etcd.io/etcd/clientv3" 我们不使用 etcd/clientv3&#xff0c;因为它与grpc 最新…...

01、Cadence使用记录之新建工程与基础操作(原理图绘制:OrCAD Capture CIS)

01、Cadence使用记录之新建工程与基础操作&#xff08;原理图绘制&#xff1a;OrCAD Capture CIS&#xff09; 硕士学电磁场去了&#xff0c;写点博客记录下学习过程。 参考的教程是B站的视频&#xff1a;allegro软件入门视频教程全集100讲 本科的时候就对Cadence有所耳闻&am…...

Redis数据结构与对象-链表和字典

1、链表 其实个人感觉redis的链表内容和其他的差不多。就是一个listNode结构&#xff0c;里面又指向前置节点和后置节点的指针。 然后redis链表可以保存各种不同类型的值。 链表被广泛用于实现redis的各种功能&#xff0c;比如列表键、发布与订阅、慢查询、监视器等。 2、字典…...

学系统集成项目管理工程师(中项)系列08a_合同管理(上)

1. 合同&#xff08;Contract&#xff09; 1.1. 契约 1.2. 广义概念 1.2.1. 以确定各种权利与义务为内容的协议&#xff0c;即只要是当事人之间达成的确定权利义务的协议均为合同&#xff0c;不管它涉及哪个法律部门及何种法律关系 1.2.2. 合同除应包括民法中的合同外&…...

【Linux 裸机篇(四)】I.MX6ULL C语言 LED 驱动

文章目录 一、汇编搭建 C 语言环境二、C 语言编写三、编写 Makefile四、链接脚本 一、汇编搭建 C 语言环境 实际工作中是很少用到汇编去写嵌入式驱动的&#xff0c;大部分情况下都是使用 C 语言去编写的。只是在开始部分用汇编来初始化一下 C 语言环境&#xff0c;比如初始化 D…...

我也曾经因安装库而抓狂,直到我遇到了

入门教程、案例源码、学习资料、读者群 请访问&#xff1a; python666.cn 大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01; 几乎所有的 Python 学习者都遇到过“安装”方面的问题。这些安装问题包括 Python 自身环境的安装、第三方模块的安装、不同版本的切换&…...

DDPG算法详解

DQN算法详解 一.概述 概括来说&#xff0c;RL要解决的问题是&#xff1a;让agent学习在一个环境中的如何行为动作(act)&#xff0c; 从而获得最大的奖励值总和(total reward)。 这个奖励值一般与agent定义的任务目标关联。 agent需要的主要学习内容&#xff1a;第一是行为策略…...

继续学c++

由于c里面有很多和c语言很像的东西&#xff0c;这里就来总结一点不像的或者要注意的&#xff0c;或者是我已经快忘记的&#xff1b; 先来一个浮点型也就是实型类型的总结&#xff1b; 知道浮点型有这两个类型&#xff1a;float和double型&#xff1b; 然后float型占四个字节…...

Day949.遗留系统之殇:为什么要对遗留系统进行现代化? -遗留系统现代化实战

遗留系统之殇&#xff1a;为什么要对遗留系统进行现代化&#xff1f; Hi&#xff0c;我是阿昌&#xff0c;今天学习记录是关于遗留系统之殇&#xff1a;为什么要对遗留系统进行现代化&#xff1f;的内容。 不知道你是否跟曾经一样&#xff0c;身处一个遗留系统的漩涡之中&…...

DAY 45 Nginx服务配置

Nginx概述 Nginx&#xff1a; Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器&#xff0c;而且支持热部署&#xff0c;几乎可以做到 7 * 24 小时不间断运行&#xff0c;即使运行几个月也不需要重新启动&#xff0c;还能在不间断服务的情况下对软件版本进行热更新。 对…...

如何收集K8S容器化部署的服务的日志?

做开发的同学都知道日志的重要性&#xff0c;日志的种类一般有接口日志、错误日志、关键步骤日志、用户操作日志等。本文主要详细讲解使用kubernetes容器化部署的服务该如何记录和收集日志。 一、使用标准输出方式 将想要记录的日志内容输出到stdout或stderr即可&#xff08;…...

python删除csv文件中的某几列或行

1. 读取数据 用pandas中的read_csv()函数读取出csv文件中的数据: import pandas as pddf pd.read_csv("comments.csv") df.head(2)用drop函数进行文件中数据的删除行或者删除列操作。 2. 删除列操作 方法一&#xff1a;假设我们要删除的列的名称为 ‘观众ID’,‘…...

Redis持久化机制导致服务自启动后恢复数据过长无法使用以及如何关闭

场景 若依前后端分离版手把手教你本地搭建环境并运行项目&#xff1a; 若依前后端分离版手把手教你本地搭建环境并运行项目_霸道流氓气质的博客-CSDN博客 在上面搭建前后端分离的项目后&#xff0c;如果需要在windows服务上进行部署。 若依前后端分离版本&#xff0c;Windo…...

DAY 37 shell免交互

Here Document 概述 常用的交互程序&#xff1a;read&#xff0c;ftp&#xff0c;passwd&#xff0c;su&#xff0c;sudo cat也可配合免交互的方式重定向输出到文件 Here Document 的作用 使用I/O重定向的方式将命令列表提供给交互式程序标准输入的一种替代品 格式 命令 …...

用python脚本从Cadence导出xdc约束文件

用python脚本从Cadence导出xdc约束文件 概述转换方法先导出csv文件修改CSV文件 CSV转XDC检查输出XDC文件csv2xdc源代码下载 概述 在Cadence设计完成带有FPGA芯片的原理图的时候&#xff0c;往往需要将FPGA管脚和网络对应关系导入vivado设计软件中&#xff0c;对于大规模FPGA管…...

【C++ 六】内存分区、引用

内存分区、引用 文章目录 内存分区、引用前言1 内存分区模型1.1 程序运行前1.2 程序运行后1.3 new 操作符 2 引用2.1 引用基本使用2.2 引用注意事项2.3 引用做函数参数2.4 引用做函数返回值2.5 引用本质2.6 常量引用 总结 前言 本文包含内存分区、引用基本使用、引用注意事项、…...

markdown基本语法

来自神秘人儿的投稿&#xff01; markdown的使用&#xff0c;可以参考https://markdown.com.cn/basic-syntax/ 标题&#xff1a;用 # 表示 段落&#xff1a;enter即可&#xff0c;两端之间有一个空行 换行&#xff1a;一行的末尾加两个或者多个空格&#xff0c;两端之间没有…...

第十篇 Spring 集成Redis

《Spring》篇章整体栏目 ————————————————————————————— 【第一章】spring 概念与体系结构 【第二章】spring IoC 的工作原理 【第三章】spring IOC与Bean环境搭建与应用 【第四章】spring bean定义 【第五章】Spring 集合注入、作用域 【第六章】…...

PADS-LOGIC项目原理图设计

最小板原理图设计 目录 1 菜单与工具使用 2 常用设置 2.1选项卡 2.2 图纸设置 2.3 颜色设置 3 设计技巧 3.1 模块化设计思路 3.2 元件放置 3.3 走线及连接符 4 原理图绘制 4.1 POWER原理图设计 4.2 MCU原理图设计 4.2.1晶振电路 4.2.2复位电路 4.2.3 BOOT电路 …...

36岁大龄程序员被裁,找了2个月工作,年包从100万降到50万,要不要接?

为了找到工作&#xff0c;你愿意接受降薪多少&#xff1f; 一位36岁的杭州程序员问&#xff1a; 36岁被裁&#xff0c;找了2个月工作&#xff0c;年包从100万降到50万&#xff0c;真心纠结&#xff0c;要不要接&#xff1f; 网友们分成了旗帜鲜明的两派&#xff0c;一派人认为不…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...