etcd之etcd curl命令(七)

1、etcd curl命令

如果需要使用v2 version api,启动etcd时候需要加入ETCD_ENABLE_V2=true参数,否则会报错404 page

not found。

1.1 启动

shell 复制代码
$ etcd -name etcd-cluster -initial-advertise-peer-urls http://192.168.165.195:2380 \
 -listen-peer-urls http://192.168.165.195:2380 \
 -initial-cluster-token etcd-cluster \
 -advertise-client-urls http://192.168.165.195:2379 \
 -listen-client-urls http://localhost:2379,http://192.168.165.195:2379 \
 -initial-cluster etcd-cluster=http://192.168.165.195:2380 \
 -initial-cluster-state new \
 --enable-v2

1.2 获取etcd信息

版本信息:

shell 复制代码
$ curl -L http://192.168.165.195:2379/version
{"etcdserver":"3.5.5","etcdcluster":"3.5.0"}

健康状态:

shell 复制代码
$ curl -L http://192.168.165.195:2379/health
{"health":"true","reason":""}

判断leader和followers:

shell 复制代码
$ curl -L http://192.168.165.195:2379/v2/stats/leader
{"leader":"7abd6357a5e6e51c","followers":{}}

查看自己的状态:

shell 复制代码
$ curl -L http://192.168.165.195:2379/v2/stats/self
{"name":"etcd-cluster","id":"7abd6357a5e6e51c","state":"StateLeader","startTime":"2023-02-15T20:15:02.926343872+08:00","leaderInfo":{"leader":"7abd6357a5e6e51c","uptime":"22m21.022576155s","startTime":"2023-02-15T20:15:03.627067903+08:00"},"recvAppendRequestCnt":0,"sendAppendRequestCnt":0}

查看store的状态:

shell 复制代码
$ curl -L http://192.168.165.195:2379/v2/stats/store
{"getsSuccess":8,"getsFail":16,"setsSuccess":5,"setsFail":0,"deleteSuccess":0,"deleteFail":0,"updateSuccess":0,"updateFail":0,"createSuccess":1,"createFail":0,"compareAndSwapSuccess":0,"compareAndSwapFail":0,"compareAndDeleteSuccess":0,"compareAndDeleteFail":0,"expireCount":1,"watchers":0}

1.3 key操作

1.3.1 新建key

新建key值为message,value为Hello world:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d value="Hello world"
{"action":"set","node":{"key":"/message","value":"Hello world","modifiedIndex":4,"createdIndex":4}}

修改key和创建key的使用方法相同。

查看key:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","modifiedIndex":4,"createdIndex":4}}

删除key:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XDELETE
{"action":"delete","node":{"key":"/message","modifiedIndex":5,"createdIndex":4},"prevNode":{"key":"/message","value":"Hello world","modifiedIndex":4,"createdIndex":4}}
1.3.2 新建带有TTL的key
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d value="Hello world" -d ttl=30
{"action":"set","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:51:00.363776467Z","ttl":30,"modifiedIndex":6,"createdIndex":6}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:51:00.363776467Z","ttl":27,"modifiedIndex":6,"createdIndex":6}}
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:51:00.363776467Z","ttl":23,"modifiedIndex":6,"createdIndex":6}}
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:51:00.363776467Z","ttl":21,"modifiedIndex":6,"createdIndex":6}}

取消key的TTL:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d value="Hello world" -d ttl=30
{"action":"set","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:54:00.564015529Z","ttl":30,"modifiedIndex":8,"createdIndex":8}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:54:00.564015529Z","ttl":27,"modifiedIndex":8,"createdIndex":8}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d value="Hello world" -d ttl= -d prevExist=true
{"action":"update","node":{"key":"/message","value":"Hello world","modifiedIndex":9,"createdIndex":8},"prevNode":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:54:00.564015529Z","ttl":20,"modifiedIndex":8,"createdIndex":8}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","modifiedIndex":9,"createdIndex":8}}

重置key的TTL:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d value="Hello world" -d ttl=30
{"action":"set","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:57:53.70367723Z","ttl":30,"modifiedIndex":10,"createdIndex":10},"prevNode":{"key":"/message","value":"Hello world","modifiedIndex":9,"createdIndex":8}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:57:53.70367723Z","ttl":26,"modifiedIndex":10,"createdIndex":10}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d ttl=30 -d refresh=true -d prevExist=true
{"action":"update","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:58:06.464823079Z","ttl":30,"modifiedIndex":11,"createdIndex":10},"prevNode":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:57:53.70367723Z","ttl":18,"modifiedIndex":10,"createdIndex":10}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello world","expiration":"2023-02-15T09:58:06.464823079Z","ttl":28,"modifiedIndex":11,"createdIndex":10}}
1.3.3 新建带有TTL的目录

创建普通目录:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/dir1 -XPUT -d dir=true
{"action":"set","node":{"key":"/dir1","dir":true,"modifiedIndex":4,"createdIndex":4}}

列出目录下所有的节点信息,最后以/结尾:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/
{"action":"get","node":{"dir":true,"nodes":[{"key":"/dir1","dir":true,"modifiedIndex":4,"createdIndex":4}]}}

还可以通过 recursive 参数递归列出所有子目录信息:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys?recursive=true
{"action":"get","node":{"dir":true,"nodes":[{"key":"/dir1","dir":true,"modifiedIndex":4,"createdIndex":4}]}}

删除目录,默认情况下只允许删除空目录,如果要删除有内容的目录需要加上recursive=true参数:

shell 复制代码
$ curl 'http://192.168.165.195:2379/v2/keys/dir1?dir=true' -XDELETE
{"action":"delete","node":{"key":"/dir1","dir":true,"modifiedIndex":5,"createdIndex":4},"prevNode":{"key":"/dir1","dir":true,"modifiedIndex":4,"createdIndex":4}}

创建带超时的目录:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/dir2 -XPUT -d ttl=30 -d dir=true
{"action":"set","node":{"key":"/dir2","dir":true,"expiration":"2023-02-15T12:15:46.015352979Z","ttl":30,"modifiedIndex":4,"createdIndex":4}}
shell 复制代码
$ curl 'http://192.168.165.195:2379/v2/keys/dir2?sorted=true'
{"action":"get","node":{"key":"/dir2","dir":true,"expiration":"2023-02-15T12:15:46.015352979Z","ttl":30,"modifiedIndex":4,"createdIndex":4}}

$ curl 'http://192.168.165.195:2379/v2/keys/dir2?sorted=true'
{"action":"get","node":{"key":"/dir2","dir":true,"expiration":"2023-02-15T12:15:46.015352979Z","ttl":27,"modifiedIndex":4,"createdIndex":4}}

向该目录插入数据:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/dir2/message -XPUT -d value="Hello world"
{"action":"set","node":{"key":"/dir2/message","value":"Hello world","modifiedIndex":5,"createdIndex":5}}

到期之前该目录的数据和普通数据一样,但是该目录到期后数据会被自动删除:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/dir2/message
{"action":"get","node":{"key":"/dir2/message","value":"Hello world","modifiedIndex":5,"createdIndex":5}}

$ curl http://192.168.165.195:2379/v2/keys/dir2/message
{"errorCode":100,"message":"Key not found","cause":"/dir2","index":6}
1.3.4 自动创建有序的key

注意,下面的/queue为目录,创建方法为POST,不是PUT:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/queue -XPOST -d value=Job1
{"action":"create","node":{"key":"/queue/00000000000000000010","value":"Job1","modifiedIndex":10,"createdIndex":10}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/queue -XPOST -d value=Job2
{"action":"create","node":{"key":"/queue/00000000000000000011","value":"Job2","modifiedIndex":11,"createdIndex":11}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/queue -XPOST -d value=Job3
{"action":"create","node":{"key":"/queue/00000000000000000012","value":"Job3","modifiedIndex":12,"createdIndex":12}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/queue -XPOST -d value=Job4
{"action":"create","node":{"key":"/queue/00000000000000000013","value":"Job4","modifiedIndex":13,"createdIndex":13}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/queue -XPOST -d value=Job5
{"action":"create","node":{"key":"/queue/00000000000000000014","value":"Job5","modifiedIndex":14,"createdIndex":14}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/queue -XPOST -d value=Job6
{"action":"create","node":{"key":"/queue/00000000000000000015","value":"Job6","modifiedIndex":15,"createdIndex":15}}

查看:

shell 复制代码
$ curl 'http://192.168.165.195:2379/v2/keys/queue?recursive=true&sorted=true'
{"action":"get","node":{"key":"/queue","dir":true,"nodes":[{"key":"/queue/00000000000000000010","value":"Job1","modifiedIndex":10,"createdIndex":10},{"key":"/queue/00000000000000000011","value":"Job2","modifiedIndex":11,"createdIndex":11},{"key":"/queue/00000000000000000012","value":"Job3","modifiedIndex":12,"createdIndex":12},{"key":"/queue/00000000000000000013","value":"Job4","modifiedIndex":13,"createdIndex":13},{"key":"/queue/00000000000000000014","value":"Job5","modifiedIndex":14,"createdIndex":14},{"key":"/queue/00000000000000000015","value":"Job6","modifiedIndex":15,"createdIndex":15}],"modifiedIndex":10,"createdIndex":10}}
1.3.5 创建一个隐藏节点

命名时名字以下划线_开头默认就是隐藏键。

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/_message -XPUT -d value="Hello hidden world"
{"action":"set","node":{"key":"/_message","value":"Hello hidden world","modifiedIndex":7,"createdIndex":7}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/_message
{"action":"get","node":{"key":"/_message","value":"Hello hidden world","modifiedIndex":7,"createdIndex":7}}

1.4 一次性watch

开启一个终端:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message?wait=true

重新打开二个终端,新建key:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d value="Hello world"
{"action":"set","node":{"key":"/message","value":"Hello world","modifiedIndex":6,"createdIndex":6}}

此时第一个终端显示如下:

shell 复制代码
{"action":"set","node":{"key":"/message","value":"Hello world","modifiedIndex":6,"createdIndex":6}}

再次在第一个终端执行watch,在第二个终端更新key:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/message -XPUT -d value="Nice Day"
{"action":"set","node":{"key":"/message","value":"Nice Day","modifiedIndex":7,"createdIndex":7},"prevNode":{"key":"/message","value":"Hello world","modifiedIndex":6,"createdIndex":6}}

第一个终端显示如下:

shell 复制代码
{"action":"set","node":{"key":"/message","value":"Nice Day","modifiedIndex":7,"createdIndex":7},"prevNode":{"key":"/message","value":"Hello world","modifiedIndex":6,"createdIndex":6}}

1.5 原子CAS操作(Compare And Swap)

CAS操作的基本用途就是创建分布式的锁服务,即选主,仅当客户端提供的条件等于当前etcd的条件时,才会修改

一个key的值。当前提供的可以比较的条件有:

  • prevExist: 检查key是否存在。如果prevExist为true,则这是一个更新请求,如果prevExist的值是false,这

    是一个创建请求

  • prevValue:检查key之前的value

  • prevIndex:检查key以前的modifiedIndex

插入一个测试key为foo,值为one:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/foo -XPUT -d value=one
{"action":"set","node":{"key":"/foo","value":"one","modifiedIndex":8,"createdIndex":8}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"one","modifiedIndex":8,"createdIndex":8}}

插入一个已存在的key并添加参数prevExist=false,因为已经有存在的key:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/foo?prevExist=false -XPUT -d value=two
{"errorCode":105,"message":"Key already exists","cause":"/foo","index":8}

将插入条件换成prevValue,即检查key的value值,条件相等就替换,否则就提示条件不匹配:

shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/foo?prevValue=three -XPUT -d value=two
{"errorCode":101,"message":"Compare failed","cause":"[three != one]","index":8}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/foo?prevValue=one -XPUT -d value=two
{"action":"compareAndSwap","node":{"key":"/foo","value":"two","modifiedIndex":9,"createdIndex":8},"prevNode":{"key":"/foo","value":"one","modifiedIndex":8,"createdIndex":8}}
shell 复制代码
$ curl http://192.168.165.195:2379/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"two","modifiedIndex":9,"createdIndex":8}}

其它操作请参考官网:https://etcd.io/。

相关推荐
螺蛳粉 螺蛳粉4 小时前
第 02 篇:镜像分层与 containerd 2.x 实战:SystemdCgroup 与 pause 镜像配置踩坑(底座认知 02)
docker·云原生·容器·kubernetes·etcd·containerd·kube-apiserver
紧跟先前的步伐7 小时前
Go AI Agent 实战 22|完善 Agent 执行循环:从工具调用到最终回答
人工智能·ai·golang
螺蛳粉 螺蛳粉8 小时前
第 03 篇:为什么 K8s 的最小调度单元是 Pod 而不是容器:pause 容器与边车模式(底座认知 03)
docker·云原生·容器·kubernetes·etcd·运维排障·kube-apiserver
后台模板学习8 小时前
Go Web开发中任务调度框架的源码解析与高可用实现方案
开发语言·后端·golang
FungLeo9 小时前
成为全栈·Go 后端篇·分类树与标签关系:目录变更为何需要协调
golang·go·gorm·数据库事务·分类树·成为全栈
fly-iot9 小时前
【FDE知识库】(1):AI 编程时代开发语言选型分析,云使用go,企业用java,算法python,底层c
开发语言·人工智能·golang
FungLeo9 小时前
成为全栈·Go 后端篇·文章查询与展示投影:安全分页、排序和软删除
golang·go·gorm·分页查询·成为全栈·sql安全
紧跟先前的步伐18 小时前
Go AI Agent 实战 24|工具系统工程化收尾与阶段验收
人工智能·ai·golang·1024程序员节
日日大王学编程19 小时前
#Feed 流项目复盘:Redis 时间线缓存与 Outbox 消息可靠性设计
golang·1024程序员节
北冥you鱼1 天前
Go 语言 CRUD 实战:从接口设计到真实业务场景
开发语言·后端·golang