一起学习ETCD系列——运维操作之etcdctl使用
文章目录
- 概要
- 一、命令
- 二、实操
- 2.1、基本操作
- 2.2、watch
- 2.3、租约
- 2.4、分布式锁
- 2.5、角色
- 2.6、用户
- 2.7、认证
- 2.8、集群
概要
本文主要用来总结ETCD客户端ctcdctl的命令操作,在运维过程中可能常常用到的。
一、命令
etcd工具
etcdctl官方命令示例
[root@test etcd-v3.5.11]# ./etcdctl -h
NAME:etcdctl - A simple command line client for etcd3.USAGE:etcdctl [flags]VERSION:3.5.11API VERSION:3.5COMMANDS: #命令alarm disarm Disarms all alarms #关闭告警alarm list Lists all alarms #列出告警信息auth disable Disables authentication #关闭认证auth enable Enables authentication #开启认证auth status Returns authentication status #查看认证状态check datascale Check the memory usage of holding data for different workloads on a given server endpoint. #检查给定实例的内存使用情况check perf Check the performance of the etcd cluster #检查etcd集群的性能compaction Compacts the event history in etcd #压缩etcd的历史事件defrag Defragments the storage of the etcd members with given endpoints #整理给定实例的存储碎片del Removes the specified key or range of keys [key, range_end) #删除keyelect Observes and participates in leader election #加入leader选举endpoint hashkv Prints the KV history hash for each endpoint in --endpoints #打印给定若干实例KV history hashendpoint health Checks the healthiness of endpoints specified in `--endpoints` flag #检查给定若干实例健康endpoint status Prints out the status of endpoints specified in `--endpoints` flag #打印给定若干实例状态get Gets the key or a range of keys #获取key值help Help about any command #打印命令帮助信息lease grant Creates leases #创建一个租约lease keep-alive Keeps leases alive (renew) #续约lease list List all active leases #列出所有租约lease revoke Revokes leases #撤销租约lease timetolive Get lease information #获取租约详情,比如剩余有效期lock Acquires a named lock #获取命名锁make-mirror Makes a mirror at the destination etcd cluster #指定一个etcd集群作为镜像集群member add Adds a member into the cluster #添加一个成员到etcd集群member list Lists all members in the cluster #列出etcd集群全部成员member promote Promotes a non-voting member in the cluster #将成员从Follower状态到Candidate状态member remove Removes a member from the cluster #移除成员member update Updates a member in the cluster #更新成员move-leader Transfers leadership to another etcd cluster member. #指定成员成为Leader状态put Puts the given key into the store #插入或更新keyrole add Adds a new role #添加新角色role delete Deletes a role #删除角色role get Gets detailed information of a role #获取角色的详细信息role grant-permission Grants a key to a role #授予角色对key的权限,比如读写role list Lists all roles #列出全部的角色role revoke-permission Revokes a key from a role #撤销角色对指定key的权限snapshot restore Restores an etcd member snapshot to an etcd directory #恢复快照到指定数据目录snapshot save Stores an etcd node backend snapshot to a given file #保存快照到指定文件snapshot status [deprecated] Gets backend snapshot status of a given file #[弃用] 获取给定快照文件的状态txn Txn processes all the requests in one transaction #开启事务user add Adds a new user #添加账户user delete Deletes a user #删除账户user get Gets detailed information of a user #获取账户详情user grant-role Grants a role to a user #指定账户角色user list Lists all users #列出所有账户user passwd Changes password of user #修改账户密码user revoke-role Revokes a role from a user #撤销账户角色version Prints the version of etcdctl #打印ectd当前版本watch Watches events stream on keys or prefixes #监听一些key或共同前缀key的事件【】OPTIONS: #命令的可选参数--cacert="" verify certificates of TLS-enabled secure servers using this CA bundle #服务端使用https时,使用ca文件进行验证--cert="" identify secure client using this TLS certificate file #指定HTTPS的TLS证书文件--command-timeout=5s timeout for short running command (excluding dial timeout) #命令执行超时时间--debug[=false] enable client-side debug logging #启用客户端调试日志,默认false--dial-timeout=2s dial timeout for client connections #指定连接超时时间-d, --discovery-srv="" domain name to query for SRV records describing cluster endpoints #用于查询描述集群端点的srv记录的域名--discovery-srv-name="" service name to query when using DNS discovery #使用DNS发现时要查询的服务名称--endpoints=[127.0.0.1:2379] gRPC endpoints #指定实例访问ip+端口-h, --help[=false] help for etcdctl--hex[=false] print byte strings as hex encoded strings #将字节字符串打印为十六进制编码字符串--insecure-discovery[=true] accept insecure SRV records describing cluster endpoints #接受描述集群端点的不安全的srv记录--insecure-skip-tls-verify[=false] skip server certificate verification (CAUTION: this option should be enabled only for testing purposes)#跳过服务器证书验证(注意:此选项应仅用于测试目的)--insecure-transport[=true] disable transport security for client connections #客户端禁用安全传输--keepalive-time=2s keepalive time for client connections #客户端连接的keepalive时间--keepalive-timeout=6s keepalive timeout for client connections #客户端连接的keepalive超时时间--key="" identify secure client using this TLS key file #使用此 TLS 密钥文件识别安全客户端--password="" password for authentication (if this option is used, --user option shouldn't include password) #用于身份验证的密码(如果使用此选项,--user 选项不应包含密码)--user="" username[:password] for authentication (prompt if password is not supplied)#用于身份验证(如果未提供密码则提示)-w, --write-out="simple" set the output format (fields, json, protobuf, simple, table) #输出格式,默认simple,个人感觉table格式看着最舒服
二、实操
etcdctl [command] -h 可以查看具体命令的使用说明:
[root@test etcd-v3.5.11]# ./etcdctl lease -h
NAME:lease - Lease related commands
USAGE:etcdctl lease <subcommand> [flags]
API VERSION:3.5
COMMANDS:grant Creates leaseskeep-alive Keeps leases alive (renew)list List all active leasesrevoke Revokes leasestimetolive Get lease information
OPTIONS:-h, --help[=false] help for lease[root@test etcd-v3.5.11]# ./etcdctl lease grant -h
NAME:lease grant - Creates leases
USAGE:etcdctl lease grant <ttl> [flags] #详细使用说明
OPTIONS:-h, --help[=false] help for grant
2.1、基本操作
#插入key
[root@test etcd-v3.5.11]# ./etcdctl put /test/key1 value1
OK
#创建500s的租约,其id为43e58d2bb5a3102d
[root@test etcd-v3.5.11]# ./etcdctl lease grant 500
lease 43e58d2bb5a3102d granted with TTL(500s)
#获取租约详情
[root@test etcd-v3.5.11]# ./etcdctl lease timetolive 43e58d2bb5a3102d
lease 43e58d2bb5a3102d granted with TTL(500s), remaining(470s)
#插入key,并指定租约
[root@test etcd-v3.5.11]# ./etcdctl put /test/key2 value2 --lease=43e58d2bb5a3102d
OK
#获取
[root@test etcd-v3.5.11]# ./etcdctl get /test/key1
/test/key1
value1
[root@test etcd-v3.5.11]# ./etcdctl get /test/key2
/test/key2
value2
#删除
[root@test etcd-v3.5.11]# ./etcdctl del /test/key2
1
[root@test etcd-v3.5.11]# ./etcdctl get /test/key1 -w josn
{"header":{"cluster_id":11073961802084797819,"member_id":8518302759694844901,"revision":10769,"raft_term":15},"kvs":[{"key":"L3Rlc3Qva2V5MQ==","create_revision":10759,"mod_revision":10761,"version":3,"value":"dmFsdWUxNA=="}],"count":1}
#cluster_id:请求的etcd集群ID。
#member_id:请求的etcd节点ID。
#revision:etcd服务端当前全局数据版本号。对任一key的put或delete操作都会使revision自增1。revision=1是etcd的保留版本号,因此用户的key版本号将从2开始。
#raft_term:etcd当前raft主节点任期号。
#create_revision:当前key创建时全局数据版本号revision的值。
#mod_revision:当前key最后一次修改时全局数据版本号revision的值。
#version:当前key的数据版本号。key创建时version为1,对当前key进行put操作会使version自增1,将key删除后,重新创建,version又会从1开始计数。
2.2、watch
监听key,可以看到key的事件
[root@test etcd-v3.5.11]# ./etcdctl watch /test/key3
PUT
/test/key3
value3
PUT
/test/key3
value31
PUT
/test/key3
value33
DELETE
/test/key3
PUT
/test/key3
value35
操作key
[root@test etcd-v3.5.11]# ./etcdctl put /test/key3 value3
OK
[root@test etcd-v3.5.11]# ./etcdctl put /test/key3 value31
OK
[root@test etcd-v3.5.11]# ./etcdctl put /test/key3 value33
OK
[root@test etcd-v3.5.11]# ./etcdctl del /test/key3
1
[root@test etcd-v3.5.11]# ./etcdctl put /test/key3 value35
OK
2.3、租约
#创建500s的租约,其id为43e58d2bb5a3102d
[root@test etcd-v3.5.11]# ./etcdctl lease grant 500
lease 43e58d2bb5a3102d granted with TTL(500s)
#获取租约详情
[root@test etcd-v3.5.11]# ./etcdctl lease timetolive 43e58d2bb5a3102d
lease 43e58d2bb5a3102d granted with TTL(500s), remaining(470s)
#只续约一次
[root@test etcd-v3.5.11]# ./etcdctl lease keep-alive --once=true 43e58d2bb5a3102d
#一直自动续约
[root@test etcd-v3.5.11]# ./etcdctl lease keep-alive 43e58d2bb5a3102d
#删除租约
[root@test etcd-v3.5.11]# ./etcdctl lease revoke 43e58d2bb5a3102d
2.4、分布式锁
etcd中分布式锁的结构是:lock_key/lease_id。
实现过程(源码)如下:
- 准备
客户端连接 Etcd,以 /lock/mylock 为前缀创建全局唯一的 key,假设第一个客户端对应的 key=“/lock/mylock/UUID1”,第二个为 key=“/lock/mylock/UUID2”;客户端分别为自己的 key 创建租约 - Lease,租约的长度根据业务耗时确定,假设为 15s; - 创建租约
当一个客户端持有锁期间,其它客户端只能等待,为了避免等待期间租约失效,客户端需创建一个定时任务作为“心跳”进行续约。此外,如果持有锁期间客户端崩溃,心跳停止,key 将因租约到期而被删除,从而锁释放,避免死锁。 - 客户端写入自己全局唯一的 key
通过 PUT 操作,将步骤 1 中创建的 key 绑定租约写入 Etcd,根据 Etcd 的 Revision 机制,假设两个客户端 put 操作返回的 Revision 分别为 1、2,客户端需记录 Revision 用以接下来判断自己是否获得锁。 - 客户端判断是否获得锁
客户端以前缀 /lock/mylock 读取 keyValue 列表(keyValue 中带有 key 对应的 Revision),判断自己 key 的 Revision 是否为当前列表中最小的,如果是则认为获得锁;否则监听列表中前一个 Revision 比自己小的 key 的删除事件,一旦监听到删除事件或者因租约失效而删除的事件,则自己获得锁。 - 执行业务
获得锁后,操作共享资源,执行业务代码。 - 释放锁
完成业务流程后,释放锁,通过删除对应的key完成。
测试:
开三个窗口
#获取锁
[root@test etcd-v3.5.11]# ./etcdctl lock /lock/test --ttl=5
/lock/test/43e58d437ddbc834
#等待锁
[root@test etcd-v3.5.11]# ./etcdctl lock /lock/test --ttl=5
#watch监控/lock/test为前缀的key变化
[root@kdzl etcd-v3.5.11]# ./etcdctl watch /lock/test --prefix
PUT
/lock/test/43e58d437ddbc834
PUT
/lock/test/43e58d437ddbc838
2.5、角色
[root@test etcd-v3.5.11]# ./etcdctl role add book
Role book created
[root@test etcd-v3.5.11]# ./etcdctl role add man
Role man created
[root@test etcd-v3.5.11]# ./etcdctl role list
book
man
[root@test etcd-v3.5.11]# ./etcdctl role get man
Role man
KV Read:
KV Write:
#给key授权角色
#etcdctl role grant-permission [options] <role name> <permission type> <key> [endkey] [flags]
[root@test etcd-v3.5.11]# ./etcdctl role grant-permission man read /test
Role man updated
[root@test etcd-v3.5.11]# ./etcdctl role get man
Role man
KV Read:/test
KV Write:
#移除key角色
[root@test etcd-v3.5.11]# ./etcdctl role revoke-permission man /test
Permission of key /test is revoked from role man
[root@test etcd-v3.5.11]# ./etcdctl role get man
Role man
KV Read:
KV Write:
2.6、用户
#创建用户
[root@test etcd-v3.5.11]# ./etcdctl user add root:root
User root created
[root@test etcd-v3.5.11]# ./etcdctl user add test --new-user-password=12345
User test created
[root@test etcd-v3.5.11]# ./etcdctl user add pick:25823
User pick created
#列出全部的用户
[root@test etcd-v3.5.11]# ./etcdctl user list
root
test
[root@test etcd-v3.5.11]# ./etcdctl user get test
User: test
Roles:
#给账号一个角色,一个账户可以有多个角色
[root@test etcd-v3.5.11]# ./etcdctl user grant-role test man
Role man is granted to user test
[root@test etcd-v3.5.11]# ./etcdctl user get test
User: test
Roles: man
#删除角色
[root@test etcd-v3.5.11]# ./etcdctl user del pick
User pick deleted
#撤销用户角色
[root@test etcd-v3.5.11]# ./etcdctl user revoke-role test man
Role man is revoked from user test
2.7、认证
启用auth需要一个root用户,并且root用户有root角色
[root@test etcd-v3.5.11]# ./etcdctl role add root
Role root created
[root@test etcd-v3.5.11]# ./etcdctl role grant-permission --prefix=true root readwrite /
Role root updated
[root@test etcd-v3.5.11]# ./etcdctl user grant-role root root
Role root is granted to user root
[root@test etcd-v3.5.11]# ./etcdctl auth enable
Authentication Enabled
[root@test etcd-v3.5.11]# ./etcdctl auth status --user=root:root
Authentication Status: true
AuthRevision: 15
换成 test 用户操作
[root@test etcd-v3.5.11]# ./etcdctl role grant-permission --prefix=true man read /test --user=root:root #对/test前缀的key有只读权限
Role man updated
[root@test etcd-v3.5.11]# ./etcdctl role get man --user=root:root
Role man
KV Read:/test
KV Write:
[root@test etcd-v3.5.11]# ./etcdctl user grant-role test man --user=root:root
Role man is granted to user test
[root@test etcd-v3.5.11]# ./etcdctl get /test/key1 --user=test:12345
/test/key1
value14
[root@test etcd-v3.5.11]# ./etcdctl put /test/key5 value5 --user=test:12345
{"level":"warn","ts":"2024-01-25T23:38:54.753123+0800","logger":"etcd-client","caller":"v3@v3.5.11/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc000362e00/127.0.0.1:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
可以看到权限生效
2.8、集群
1:查看每个实例状态,即检查etcd集群状态
[root@test etcd-v3.5.11]# ./etcdctl endpoint status -w table --endpoints"=127.0.0.1:2379,127.0.0.1:2369,127.0.0.1:2359"
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 127.0.0.1:2379 | 7637173a60d743e5 | 3.5.11 | 21 MB | true | false | 15 | 10923 | 10923 | |
| 127.0.0.1:2369 | ce6b0efed2935560 | 3.5.11 | 21 MB | false | false | 15 | 10923 | 10923 | |
| 127.0.0.1:2359 | 6ea1523f71bf92f0 | 3.5.11 | 21 MB | false | false | 15 | 10923 | 10923 | |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
2:查看健康状态
#TOOK表示心跳
[root@test etcd-v3.5.11]# ./etcdctl endpoint health --endpoints="127.0.0.1:2379,127.0.0.1:2369,127.0.0.1:2359" -w table
+----------------+--------+-------------+-------+
| ENDPOINT | HEALTH | TOOK | ERROR |
+----------------+--------+-------------+-------+
| 127.0.0.1:2369 | true | 16.178532ms | |
| 127.0.0.1:2379 | true | 17.826437ms | |
| 127.0.0.1:2359 | true | 19.841588ms | |
+----------------+--------+-------------+-------+
[root@test etcd-v3.5.11]# ./etcdctl endpoint hashkv --endpoints="127.0.0.1:2379,127.0.0.1:2369,127.0.0.1:2359" -w table
+----------------+------------+
| ENDPOINT | HASH |
+----------------+------------+
| 127.0.0.1:2379 | 2618695019 |
| 127.0.0.1:2369 | 2618695019 |
| 127.0.0.1:2359 | 2618695019 |
+----------------+------------+
3:切换集群leader
原来集群leader实例是127.0.0.1:2379
,现在通过move-leader
命令将leader切换成实例127.0.0.1:2359
[root@test etcd-v3.5.11]# ./etcdctl move-leader 6ea1523f71bf92f0 --endpoints="127.0.0.1:2379,127.0.0.1:2369,127.0.0.1:2359"
Leadership transferred from 7637173a60d743e5 to 6ea1523f71bf92f0
[root@test etcd-v3.5.11]# ./etcdctl endpoint status --endpoints="127.0.0.1:2379,127.0.0.1:2369,127.0.0.1:2359" -w table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 127.0.0.1:2379 | 7637173a60d743e5 | 3.5.11 | 21 MB | false | false | 19 | 10933 | 10933 | |
| 127.0.0.1:2369 | ce6b0efed2935560 | 3.5.11 | 21 MB | false | false | 19 | 10933 | 10933 | |
| 127.0.0.1:2359 | 6ea1523f71bf92f0 | 3.5.11 | 21 MB | true | false | 19 | 10933 | 10933 | |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
4:查看集群成员
[root@test etcd-v3.5.11]# ./etcdctl member list -w table
+------------------+---------+--------+-----------------------+-----------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+--------+-----------------------+-----------------------+------------+
| 6ea1523f71bf92f0 | started | etcd3 | http://127.0.0.1:2360 | http://127.0.0.1:2359 | false |
| 7637173a60d743e5 | started | etcd1 | http://127.0.0.1:2380 | http://127.0.0.1:2379 | false |
| ce6b0efed2935560 | started | etcd2 | http://127.0.0.1:2370 | http://127.0.0.1:2369 | false |
+------------------+---------+--------+-----------------------+-----------------------+------------+
5:添加成员(一个learner成员,不参与投票)
1)etcdctl member add 命令将新成员添加到集群
[root@testl etcd-v3.5.11]# ./etcdctl member add etcd04 --peer-urls="http://127.0.0.16:2350" --learner=true
Member 690b31e00158f43a added to cluster 99ae9d962d824d7bETCD_NAME="etcd4"
ETCD_INITIAL_CLUSTER="etcd4=http://127.0.0.1:2350,etcd3=http://127.0.0.1:2360,etcd1=http://127.0.0.1:2380,etcd2=http://127.0.0.1:2370"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://127.0.0.1:2350"
ETCD_INITIAL_CLUSTER_STATE="existing"
#可以看到该成员尚未启动
[root@test etcd-v3.5.11]# ./etcdctl member list -w table
+------------------+-----------+--------+----------------------------+-----------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+-----------+--------+----------------------------+-----------------------+------------+
| 690b31e00158f43a | unstarted | | http://127.0.0.1:2350 | | true |
| 6ea1523f71bf92f0 | started | etcd3 | http://127.0.0.1:2360 | http://127.0.0.1:2359 | false |
| 7637173a60d743e5 | started | etcd1 | http://127.0.0.1:2380 | http://127.0.0.1:2379 | false |
| ce6b0efed2935560 | started | etcd2 | http://127.0.0.1:2370 | http://127.0.0.1:2369 | false |
+------------------+-----------+--------+----------------------------+-----------------------+------------+
2)启动新成员
回溯集群安装篇
配置文件如下:
mkdir -p /usr/local/etcd-v3.5.11/etcd4/data
vim /usr/local/etcd-v3.5.11/etcd4/conf.yml
name: etcd4
data-dir: /usr/local/etcd-v3.5.11/etcd4/data
initial-advertise-peer-urls: http://127.0.0.1:2350
listen-peer-urls: http://127.0.0.1:2350
listen-client-urls: http://172.20.101.222:2349,http://127.0.0.1:2349
advertise-client-urls: http://127.0.0.1:2349
initial-cluster-token: test-etcd-cluster
initial-cluster: etcd1=http://127.0.0.1:2380,etcd2=http://127.0.0.1:2370,etcd3=http://127.0.0.1:2360,etcd4=http://127.0.0.1:2350
initial-cluster-state: existing #注意,这里一定要标记为existing
/usr/local/etcd-v3.5.11/etcd --config-file /usr/local/etcd-v3.5.11/etcd4/conf.yml
可以看到已经成功加入集群
[root@test etcd-v3.5.11]# ./etcdctl member list -w table
+------------------+---------+--------+-----------------------+-----------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+--------+-----------------------+-----------------------+------------+
| 6ea1523f71bf92f0 | started | etcd3 | http://127.0.0.1:2360 | http://127.0.0.1:2359 | false |
| 7637173a60d743e5 | started | etcd1 | http://127.0.0.1:2380 | http://127.0.0.1:2379 | false |
| c64a0c36c4a5869f | started | etcd4 | http://127.0.0.1:2350 | http://127.0.0.1:2349 | true |
| ce6b0efed2935560 | started | etcd2 | http://127.0.0.1:2370 | http://127.0.0.1:2369 | false |
+------------------+---------+--------+-----------------------+-----------------------+------------+
6:learner成员提升为follower成员
实例http://127.0.0.1:2350
还是learner,没有投票权,用member promote
命令提升下
[root@test etcd-v3.5.11]# ./etcdctl member promote c64a0c36c4a5869f
Member c64a0c36c4a5869f promoted in cluster 99ae9d962d824d7b
[root@test etcd-v3.5.11]# ./etcdctl member list -w table
+------------------+---------+--------+-----------------------+-----------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+--------+-----------------------+-----------------------+------------+
| 6ea1523f71bf92f0 | started | etcd3 | http://127.0.0.1:2360 | http://127.0.0.1:2359 | false |
| 7637173a60d743e5 | started | etcd1 | http://127.0.0.1:2380 | http://127.0.0.1:2379 | false |
| c64a0c36c4a5869f | started | etcd4 | http://127.0.0.1:2350 | http://127.0.0.1:2349 | false | #可以看到已经不是learner了
| ce6b0efed2935560 | started | etcd2 | http://127.0.0.1:2370 | http://127.0.0.1:2369 | false |
+------------------+---------+--------+-----------------------+-----------------------+------------+
相关文章:

一起学习ETCD系列——运维操作之etcdctl使用
文章目录 概要一、命令二、实操2.1、基本操作2.2、watch2.3、租约2.4、分布式锁2.5、角色2.6、用户2.7、认证2.8、集群 概要 本文主要用来总结ETCD客户端ctcdctl的命令操作,在运维过程中可能常常用到的。 一、命令 etcd工具 etcdctl官方命令示例 [roottest etcd…...

Spring Security 存储密码之 JDBC
Spring Security的JdbcDaoImpl实现了UserDetailsService接口,通过使用JDBC提供支持基于用户名和密码的身份验证。 JdbcUserDetailsManager扩展了JdbcDaoImpl,通过UserDetailsManager接口提供UserDetails的管理功能。 当Spring Security配置为接受用户名/密码进行身份验证时,…...

第3章-python深度学习——(波斯美女)
第3章 神经网络入门 本章包括以下内容: 神经网络的核心组件 Keras 简介 建立深度学习工作站 使用神经网络解决基本的分类问题与回归问题 本章的目的是让你开始用神经网络来解决实际问题。你将进一步巩固在第 2 章第一个示例中学到的知识,还会将学到的…...

蓝桥杯备战——4.继电器/蜂鸣器
1.分析原理图 最好自己先去查查138以及ULN2003的使用方法,我这里直接讲思路。 由上图我们可以看到如果138输入ABC101,则输出Y50,此时若WR通过跳线帽接地则Y5C1 ,于是573(U9)处于输出跟随输入P0状态,此时若P061,则573输出Q71&am…...

Redis高级特性之地理空间索引
Redis的地理空间索引是一种功能强大的工具,用于存储和查询地理空间数据。这个特性主要通过Redis的地理空间数据类型 - GeoSet(地理集合)来实现。在这篇文章中,我们将探索Redis地理空间数据类型的使用和应用。 1. Redis GeoSet 简…...

R语言【taxlist】——as():将 taxlist 对象强制转换为 list 对象
Package taxlist version 0.2.4 Description 可以应用 S4 对象到 list 对象的强制转换来探索它们的内容,避免由它们的验证引起的错误。 Usage S4_to_list(x) Argument 参数【x】:一个 taxlist 类对象或任意 S4 类。 Details 将 taxlist 对象强制转换…...

使用POI生成word文档的table表格
文章目录 使用POI生成word文档的table表格1. 引入maven依赖2. 生成table的两种方式介绍2.1 生成一行一列的table2.2 生成固定行列的table2.3 table合并列2.4 创建多个table存在的问题 使用POI生成word文档的table表格 1. 引入maven依赖 <dependency><groupId>org.…...

C# 继承、多态性、抽象和接口详解:从入门到精通
C# 继承 在 C# 中,可以将字段和方法从一个类继承到另一个类。我们将“继承概念”分为两类: 派生类(子类) - 从另一个类继承的类基类(父类) - 被继承的类 要从一个类继承,使用 : 符号。 在以…...

python在线聊天室(带聊天保存)
python Socket在线聊天室(带聊天保存) 需求功能 1.聊天信息保存功能(服务端会把信息保存到一个txt里面) 2.使用pyqt5框架作为一个可视化界面 3.具备一个服务端和多个客户端的功能 4.具备离线加入黑名单(离线踢出) 5.具备在线加入黑名单(在线加入黑名单被踢出) 6.具备群聊功能…...

jenkins+gitlab实现Android自动打包填坑之旅
一.背景 1.首先你需要知道你想要实现的Android自动打包的Android项目的一些环境配置及需要使用的一些开发版本。 声明:本文 Android项目基于:1.jdk11 2.SDK无要求 3.gradle无要求(同Manven一样为项目自动化构建开源工具) 注&am…...

洛谷B3625迷宫寻路
迷宫寻路 题目描述 机器猫被困在一个矩形迷宫里。 迷宫可以视为一个 n m n\times m nm 矩阵,每个位置要么是空地,要么是墙。机器猫只能从一个空地走到其上、下、左、右的空地。 机器猫初始时位于 ( 1 , 1 ) (1, 1) (1,1) 的位置,问能否…...

GPT-SoVITS 测试
开箱直用版(使用 AutoDL) step1 打开地址 https://www.codewithgpu.com/i/RVC-Boss/GPT-SoVITS/GPT-SoVITS-Official 选择 AutoDL创建实例,选择 3080ti 机器 step2 创建好实例之后,进入命令行,输入命令 echo {}>…...

人工智能:更多有用的 Python 库
目录 前言 推荐 JupyterLab 入门 复杂的矩阵运算 其它人工智能和机器学习的 Python 库 前言 在这篇文章中,我们将了解更多的矩阵操作,同时再介绍几个人工智能 Python 库。 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂&#x…...

Linux BIO如何下发到HDD?
在Linux操作系统中,当创建一个Block I/O请求(BIO)时,它会被封装成适合硬件交互的数据结构,并通过内核存储子系统传递到对应的硬件控制器上,如SAS(Serial Attached SCSI)HBAÿ…...

《动手学深度学习(PyTorch版)》笔记4.6
注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过。…...

Hadoop-MapReduce-源码跟读-客户端篇
一、源码下载 下面是hadoop官方源码下载地址,我下载的是hadoop-3.2.4,那就一起来看下吧 Index of /dist/hadoop/core 二、从WordCount进入源码 用idea将源码加载进来后,找到org.apache.hadoop.examples.WordCount类(快捷方法&…...

《游戏-03_3D-开发》之—新输入系统人物移动攻击连击
本次修改unity的新输入输出系统。本次修改unity需要重启,请先保存项目, 点击加号起名为MyCtrl, 点击加号设置为一轴的, 继续设置W键, 保存 生成自动脚本, 修改MyPlayer代码: using UnityEngine;…...

滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编
滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编 一、Switch语句1、switch语句 是if语句的简写2、break加与不加有什么特点?default语句可以省略吗?3、游戏中的switch语句(示例)4、添加case后面的值,一个一个增加&…...

燃烧的指针(三)
🌈个人主页:小田爱学编程 🔥 系列专栏:c语言从基础到进阶 🏆🏆关注博主,随时获取更多关于c语言的优质内容!🏆🏆 😀欢迎来到小田代码世界~ &#x…...

微服务架构实施攻略:如何选择合适的微服务通信机制?
随着业务的快速发展和系统的日益复杂,传统的单体应用逐渐显露出瓶颈,已无法满足现代软件研发的需求。微服务架构作为一种灵活、可扩展的解决方案,通过将复杂系统拆分为一系列小型服务来提高系统的可伸缩性、灵活性和可维护性。在实施微服务架…...

【jetson笔记】解决vscode远程调试qt.qpa.xcb: could not connect to display报错
配置x11转发 jetson远程安装x11转发 安装Xming Xming下载 安装完成后打开安装目录C:\Program Files (x86)\Xming 用记事本打开X0.hosts文件,添加jetson IP地址 后续IP改变需要重新修改配置文件 localhost 192.168.107.57打开Xlaunch Win菜单搜索Xlaundch打开 一…...

网络安全产品之认识安全隔离网闸
文章目录 一、什么是安全隔离网闸二、安全隔离网闸的主要功能三、安全隔离网闸的工作原理四、安全隔离网闸的分类五、安全隔离网闸与防火墙的区别四、安全隔离网闸的应用场景 随着互联网的发展,网络攻击和病毒传播的方式越来越复杂,对网络安全的要求也越…...

Java通过模板替换实现excel的传参填写
以模板为例子 将上面$转义的内容替换即可 package com.gxuwz.zjh.util;import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*; import java.util.HashMap; import java.util.Map; import java.io.IOException; impor…...

眼底增强型疾病感知蒸馏模型 FDDM:无需配对,fundus 指导 OCT 分类
眼底增强型疾病感知蒸馏模型 FDDM:fundus 指导 OCT 分类 核心思想设计思路训练和推理 效果总结子问题: 疾病特定特征的提取与蒸馏子问题: 类间关系的理解与建模 核心思想 论文:https://arxiv.org/pdf/2308.00291.pdf 代码:https://github.c…...

代码随想录算法刷题训练营day17
代码随想录算法刷题训练营day17:LeetCode(110)平衡二叉树 LeetCode(110)平衡二叉树 题目 代码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(…...

Java集合如何选择
为什么使用集合 当需要存储一组类型相同的数据时,数组是最常用且最基本的容器之一。但是,使用数组存储对象存在一些不足之处,因为在实际开发中,存储的数据类型多种多样且数量不确定。这时,Java 集合就派上用场了。与数…...

简单介绍----微服务和Spring Cloud
微服务和SpringCloud 1.什么是微服务? 微服务是将一个大型的、单一的应用程序拆分成多个小型服务,每个服务负责实现特定的业务功能,并且可以通过网络通信与其他服务通信。微服务的优点是开发更灵活(不同的微服务可以使用不同的开…...

Jenkins邮件推送配置
目录 涉及Jenkins插件: 邮箱配置 什么是授权码 在第三方客户端/服务怎么设置 IMAP/SMTP 设置方法 POP3/SMTP 设置方法 获取授权码: Jenkins配置 从Jenkins主面板System configuration>System进入邮箱配置 在Email Extension Plugin 邮箱插件…...

硬件知识(1) 手机的长焦镜头
#灵感# 手机总是配备好几个镜头,研究一下 目录 手机常配备的摄像头,及效果举例 长焦的焦距 焦距的定义和示图: IPC的焦距和适用场景: 手机常配备的摄像头,及效果举例 以下是小米某个手机的摄像头介绍:…...

华为机考入门python3--(3)牛客3-明明的随机数
分类:集合、排序 知识点: 集合添加元素 set.add(element) 集合转列表 list(set) 列表排序 list.sort() 题目来自【牛客】 N int(input().strip()) nums set()for i in range(N):nums.add(int(input().strip()))# 集合转列表 nums_list l…...