一文读懂Etcd及其原理和应用场景

news2024/11/17 17:26:12

文章目录

  • 0. 前言
  • 1. ETCD的概念和设计
  • 2.ETCD的命令示例
      • 查看ETCD的版本信息
      • 列出ETCD集群中的成员
      • 检查ETCD集群的健康状态
      • 获取指定key的值
      • 设置指定key的值
      • 删除指定key及其对应的值
      • 监控指定key的变化
      • 将ETCD的数据备份到指定文件中
  • 3. ETCD的使用场景
  • 4. ETCD的优缺点
  • 5. 配置文件示例
  • 6. Etcd对比Redis核心有点
    • 其他维度对比
  • 6. Spring boot 集成etcd实例
    • 6.1. 添加Maven依赖
    • 6.2. 配置Etcd连接信息
    • 6.3. 注入EtcdClient
    • 6.4. 使用Etcd进行配置管理
    • 6.5. 启用配置刷新
  • 7.参考资料

0. 前言

Etcd是一个开源的、高可用的、分布式的键值存储系统,可以用于存储关键的配置数据、服务发现、服务注册等。它使用Raft一致性算法来保证数据的一致性,并使用分布式锁机制来实现并发控制。Etcd支持HTTP API和gRPC API,提供了多种客户端库,可以方便地与各种编程语言进行集成。在云原生应用和微服务架构中,Etcd被广泛应用于服务发现、配置管理、分布式锁等场景。本文将介绍Etcd的原理、应用场景和使用方法,帮助读者更好地理解和应用Etcd。

1. ETCD的概念和设计

ETCD是一个分布式键值存储系统,类似于一个分层的键值对,其中键和值都是字符串类型。ETCD将所有数据都存储为键值对,支持将键值对组织成层次结构,目录是一种特殊的键,可以包含其他键值对或子目录。

ETCD的核心概念包括:

  • 键值对:ETCD中的数据都以键值对的形式进行存储,其中键和值都是字符串类型。
  • 目录:ETCD支持将键值对组织成层次结构,目录是一种特殊的键,可以包含其他键值对或子目录。
  • 事务:ETCD支持原子性的事务操作,可以一次性执行多个读写操作,保证数据的一致性。
  • 触发器:ETCD支持对键值对的修改进行监控,并在发生变化时触发相应的操作。

ETCD使用Raft算法来保证数据一致性和高可用性,Raft是一种分布式共识算法,可以保证多个节点之间的数据一致性。ETCD还使用gRPC协议进行通信,提供了高效的数据传输和处理能力。
在这里插入图片描述

2.ETCD的命令示例

以下是一些常用的ETCD命令的详细解释:

查看ETCD的版本信息

命令:

etcdctl version

执行结果:

etcdctl version: 3.5.0
API version: 3.5

列出ETCD集群中的成员

命令:

etcdctl member list

执行结果:

c7a5d5c9f3a7d6f4, started, etcd1, https://192.168.1.101:2380, https://192.168.1.101:2379, false
d9f0a9b8c7b6a5f4, started, etcd2, https://192.168.1.102:2380, https://192.168.1.102:2379, false
e8f9b8a7d6c5b4a3, started, etcd3, https://192.168.1.103:2380, https://192.168.1.103:2379, false

检查ETCD集群的健康状态

命令:

etcdctl cluster-health

执行结果:

member c7a5d5c9f3a7d6f4 is healthy: got healthy result from https://192.168.1.101:2379
member d9f0a9b8c7b6a5f4 is healthy: got healthy result from https://192.168.1.102:2379
member e8f9b8a7d6c5b4a3 is healthy: got healthy result from https://192.168.1.103:2379
cluster is healthy

获取指定key的值

命令:

etcdctl get key

执行结果:

value

设置指定key的值

命令:

etcdctl put key value

执行结果:

OK

删除指定key及其对应的值

命令:

etcdctl del key

执行结果:

1

监控指定key的变化

在这里插入图片描述

命令:

etcdctl watch key

执行结果:

watching key for changes...

将ETCD的数据备份到指定文件中

命令:

etcdctl backup file

执行结果:

{"header":{"cluster_id":1234567890123456789,"member_id":1234567890123456789,"revision":1234567890,"raft_term":1234}}
{"key":"L3Zhci93d3cva...."}

注意:上述命令的结果中,$符号表示命令行提示符,不属于命令的一部分。

3. ETCD的使用场景

ETCD作为一个分布式键值存储系统,不仅可以存储和管理数据,还可以帮助开发人员实现各种分布式应用场景,包括服务发现、配置管理、分布式锁和选举算法等。这些功能可以大大简化分布式系统的开发和维护工作,提高系统的可用性和稳定性。

  1. 服务发现
    ETCD可以帮助开发人员轻松发现各种服务,并提供相应的负载均衡策略,以确保服务的高可用性和稳定性。通过将服务注册到ETCD中,其他服务或客户端可以通过查询ETCD获取服务的地址和端口信息,以便进行调用。此外,ETCD还支持基于服务标签的服务发现,可以根据不同的标签对服务进行分类和过滤,以便更好地管理和使用服务。
    在这里插入图片描述

  2. 配置管理
    ETCD可以帮助开发人员集中管理和维护各种配置信息,包括数据库连接信息、服务端口等。通过将配置信息存储在ETCD中,可以实现统一的配置管理和版本控制,以便更好地维护和更新配置信息。此外,ETCD还支持配置变更通知功能,可以在配置信息发生变更时自动通知相关服务或客户端,以便及时更新配置信息。
    在这里插入图片描述

  3. 分布式锁
    ETCD可以帮助开发人员实现分布式锁,以确保多个节点之间的数据一致性和互斥性。通过使用ETCD提供的分布式锁机制,可以在分布式环境中实现数据的原子性操作,避免多个节点之间的竞争和冲突。此外,ETCD还支持租约机制,可以设置锁的过期时间和自动续约等功能,以便更好地管理和使用分布式锁。
    在这里插入图片描述

  4. 选举算法
    ETCD可以帮助开发人员实现分布式选举算法,以确保各个节点之间的数据一致性。通过使用ETCD提供的选举算法,可以在分布式环境中实现主从节点的切换和数据同步,以便更好地管理和维护分布式系统。此外,ETCD还支持基于租约的选举机制,可以在节点失效或网络分区发生时自动进行主从切换,以保证数据的可用性和一致性。

4. ETCD的优缺点

ETCD作为一个分布式键值存储系统,具有许多优点和缺点。在使用ETCD时需要考虑实际需求和限制,以便更好地利用其优势和避免其缺点。

优点缺点
高可用性:ETCD使用Raft算法来保证数据的一致性和高可用性。对于小规模应用来说,ETCD可能会带来额外的复杂性和开销。
分布式事务:ETCD支持原子性的事务操作,可以一次性执行多个读写操作,保证数据的一致性。ETCD需要部署在集群中的多个节点上,如果节点之间的网络连接不稳定,可能会影响数据的一致性和可用性。
快速响应:ETCD使用gRPC协议进行通信,提供了高效的数据传输和处理能力。ETCD的存储能力和性能受到硬件和网络环境的限制。在处理大量数据或高并发请求时,可能需要增加节点数量或升级硬件设备。
简单易用:ETCD提供了简单易用的命令行工具和API,可以方便地管理和维护数据。

5. 配置文件示例

ETCD的配置项很多

# etcd 配置文件示例

# 集群名称
name = "etcd-cluster"

# 监听客户端请求的地址,可以指定多个地址
listen-client-urls = "http://0.0.0.0:2379,http://0.0.0.0:4001"

# 监听同伴节点请求的地址,可以指定多个地址
listen-peer-urls = "http://0.0.0.0:2380,http://0.0.0.0:7001"

# 数据目录
data-dir = "/var/lib/etcd"

# 初始集群节点配置,可以指定多个节点
initial-cluster = "etcd-1=http://10.0.0.1:2380,etcd-2=http://10.0.0.2:2380,etcd-3=http://10.0.0.3:2380"

# 初始集群状态
initial-cluster-state = "new"

# 自动压缩模式
auto-compaction-mode = "periodic"

# 自动压缩的保留时间
auto-compaction-retention = "1h"

# 自动压缩的大小
auto-compaction-size = "100MB"

# 启用TLS证书认证
client-transport-security = {
  cert-file = "/path/to/client/cert.pem",
  key-file = "/path/to/client/key.pem",
  trusted-ca-file = "/path/to/ca.pem",
  client-cert-auth = true,
}

# 启用同伴节点TLS证书认证
peer-transport-security = {
  cert-file = "/path/to/peer/cert.pem",
  key-file = "/path/to/peer/key.pem",
  trusted-ca-file = "/path/to/ca.pem",
  client-cert-auth = true,
}

# 是否启用TLS客户端身份验证
client-cert-auth = true

# 证书和密钥文件路径
cert-file = "/path/to/server/cert.pem"
key-file = "/path/to/server/key.pem"

# 证书颁发机构CA证书路径
trusted-ca-file = "/path/to/ca.pem"

# 证书吊销列表路径
crl-file = "/path/to/crl.pem"

# 客户端证书过期时间
client-cert-allowed-cn = ["example.com", "example.org"]
client-cert-max-epoch = 100
client-cert-min-epoch = 10

# 启用安全客户端端口
client-security = {
  ca-file = "/path/to/ca.pem",
  cert-file = "/path/to/client/cert.pem",
  key-file = "/path/to/client/key.pem",
  client-cert-auth = true,
}

# 启用安全同伴节点端口
peer-security = {
  ca-file = "/path/to/ca.pem",
  cert-file = "/path/to/peer/cert.pem",
  key-file = "/path/to/peer/key.pem",
  client-cert-auth = true,
}

# 集群内部通信安全策略
peer-client-cert-auth = true
peer-trusted-ca-file = "/path/to/ca.pem"
peer-cert-file = "/path/to/etcd-peer.pem"
peer-key-file = "/path/to/etcd-peer-key.pem"
peer-cert-allowed-cn = ["etcd-1", "etcd-2", "etcd-3"]
peer-cert-max-epoch = 100
peer-cert-min-epoch = 10

# 启用TLS客户端身份验证
client-cert-auth = true

# 集群内部通信安全策略(v3.4.0+)
peer-cert-allowed-san = ["etcd-1", "etcd-2", "etcd-3"]

# 集群内部通信安全策略(v3.5.0+)
peer-cert-allowed-dns-names = ["etcd-1", "etcd-2", "etcd-3"]

# 集群内部通信安全策略(v3.6.0+)
peer-cert-allowed-email-addresses = ["etcd-1@example.com", "etcd-2@example.com", "etcd-3@example.com"]

# TLSv1.0协议启用状态
tls-min-version = "TLSv1.0"

# TLSv1.2协议启用状态
tls-max-version = "TLSv1.2"

# HTTP/2协议启用状态
http2 = true

# HTTP/2流最大并发数
http2-max-concurrent-streams = 1000

# HTTP/2流最大队列大小
http2-max-requests = 1000

# HTTP/2连接最大并发数
http2-max-sessions = 1000

# 代理协议启用状态
proxy-protocol = true

# 健康检查端口
healthcheck-port = 2381

# 健康检查时的超时时间
healthcheck-timeout = "5s"

# 健康检查时的间隔时间
healthcheck-interval = "10s"

# 健康检查时的容忍失败次数
healthcheck-fails = 3

# 是否启用raft协议
enable-v2 = true

# 是否启用v3版本API
enable-v3 = true

# 是否启用v3版本自动同步
auto-sync = true

# 是否启用v3版本自动压缩
auto-compaction-retention = "1h"
auto-compaction-size = "100MB"

# 是否开启v3版本后台压缩
backend-batch-limit = 1000
backend-batch-interval = "5s"

# 是否启用v3版本的限流措施
quota-backend-bytes = "10GB"

# 是否启用v3版本的统计信息
enable-v3-stats = true

# 是否启用v3版本的流量控制
enable-v3-flow-control = true

# 是否启用v3版本的预写日志
wal-dir = "/var/lib/etcd/wal"
wal-enable-sync = true
wal-flush-interval = "5s"

# 是否启用v3版本的备份和恢复
backup-dir = "/var/lib/etcd/backup"

# 是否启用v3版本的故障转移
enable-v3-failover = true

# 是否启用v3版本的自动选举
auto-election = true

# 是否启用v3版本的快照
snapshot-count = 10000
snapshot-interval = "30m"

# 是否启用v3版本的预选
pre-vote = true

# 是否启用v3版本的后选
post-vote = true

# 是否启用v3版本的存储
storage-backend = "v3io"

# 是否启用v3版本的存储区域
storage-region = "us-west-2"

# 是否启用v3版本的存储桶
storage-bucket = "etcd-backup"

# 是否启用v3版本的存储密钥
storage-access-key = "XXXXXXXXXXXXXXXXXXXX"

# 是否启用v3版本的存储密码
storage-secret-key = "XXXXXXXXXXXXXXXXXXXX"

# 是否启用v3版本的存储加密
storage-encryption = true

# 是否启用v3版本的存储压缩
storage-compression = true

# 是否启用v3版本的存储版本控制
storage-versioning = true

# 是否启用v3版本的存储访问控制
storage-acl = "private"

# 是否启用v3版本的存储缓存
storage-cache = "memcached"

# 是否启用v3版本的存储缓存地址
storage-cache-addresses = ["127.0.0.1:11211"]

# 是否启用v3版本的存储缓存超时时间
storage-cache-timeout = "5s"

# 是否启用v3版本的存储缓存大小
storage-cache-size = "100MB"

# 是否启用v3版本的存储缓存压缩
storage-cache-compression = true

# 是否启用v3版本的存储缓存最大值
storage-cache-max-value-size = "1MB"

# 是否启用v3版本的存储缓存清理间隔
storage-cache-eviction-interval = "10s"

# 是否启用v3版本的存储缓存清理最大值
storage-cache-eviction-max-items = 1000

# 是否启用v3版本的存储缓存清理策略
storage-cache-eviction-policy = "LRU"

# 是否启用v3版本的存储缓存清理大小
storage-cache-eviction-size = "100MB"

 

6. Etcd对比Redis核心有点

  • 支持ACID事务,可以保证数据的一致性和完整性。
  • 支持服务发现、配置管理、分布式锁、选举算法等分布式应用场景。
  • 支持TLS加密和访问控制,可以保证数据的安全性和隐私性。
  • 支持多种API和语言,例如gRPC、RESTful API、Go、Java等。
  • 支持水平扩展和垂直扩展,可以根据实际需求灵活扩展。

其他维度对比

维度ETCDRedis
数据模型键值存储键值存储
数据类型支持字符串、列表、集合、字典等数据类型支持字符串、列表、集合、有序集合等数据类型
数据一致性采用Raft算法保证数据的一致性和高可用性,可应用于分布式场景采用主从同步和哨兵机制保证数据的一致性和高可用性,可应用于缓存场景
数据持久化支持持久化和快照机制,可以将数据保存到磁盘中,数据可靠性高支持持久化和快照机制,可以将数据保存到磁盘中,数据可靠性高
分布式支持支持集群模式,可以部署在多个节点上,支持数据分片和复制等特性支持主从复制和哨兵机制,可以部署在多个节点上,支持数据分片和复制等特性
性能支持高并发和大规模数据处理,适合于分布式场景支持高并发和大规模数据处理,适合于缓存场景
功能支持服务发现、配置管理、分布式锁、选举算法等分布式应用场景支持缓存、消息队列、计数器、发布/订阅等缓存应用场景
API和语言支持支持多种API和语言,例如gRPC、RESTful API、Go、Java等支持多种API和语言,例如Redis协议、Java、Python等
数据库支持支持嵌入式数据库和外部数据库,例如SQLite、MySQL等不支持外部数据库,但支持AOF和RDB持久化机制
事务支持ACID事务,可以保证数据的一致性和完整性不支持ACID事务,但支持MULTI/EXEC、WATCH等机制
安全支持TLS加密和访问控制,可以保证数据的安全性和隐私性支持密码认证和网络隔离等机制,可以保证数据的安全性和隐私性
可扩展性支持水平扩展和垂直扩展,可以根据实际需求灵活扩展支持水平扩展和垂直扩展,可以根据实际需求灵活扩展
社区活跃度开源社区活跃度高,更新迭代频繁,支持多种开源项目和组件开源社区活跃度高,更新迭代频繁,支持多种开源项目和组件

6. Spring boot 集成etcd实例

6.1. 添加Maven依赖

在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-etcd</artifactId>
    <version>3.0.3</version>
</dependency>

6.2. 配置Etcd连接信息

在application.properties文件中添加Etcd连接信息:

spring.cloud.etcd.enabled=true
spring.cloud.etcd.uris=http://localhost:2379

6.3. 注入EtcdClient

在需要使用Etcd的地方,注入EtcdClient:

import org.springframework.cloud.etcd.config.EtcdClient;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {

    @Autowired
    private EtcdClient etcdClient;

    public void doSomething() {
        // 使用etcdClient进行操作
    }

}

6.4. 使用Etcd进行配置管理

在Etcd中创建一个key-value对:

$ etcdctl put /config/myapp/foo bar

在Spring Boot中使用该key:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@Component
@RefreshScope
public class MyComponent {

    @Value("${foo}")
    private String foo;

    public void doSomething() {
        // 使用foo进行操作
    }

}

6.5. 启用配置刷新

如果需要在Etcd中更新配置后自动刷新Spring Boot中的配置,需要在application.properties文件中添加以下配置:

spring.cloud.etcd.config.refresh.enabled=true
spring.cloud.etcd.config.refresh.interval=5

其中,refresh.interval配置项指定了配置刷新的时间间隔(单位为秒)。

7.参考资料

  • 官方文档 https://etcd.io/docs/v3.5/quickstart/
  • GitHub仓库:https://github.com/etcd-io/etcd
  • 官方论坛:https://discuss.etcd.io/
  • 分布式键值存储系统—Etcd

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

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

相关文章

Spring boot 集成 Skywalking 配置 || Skywalking 打不开【已解决】

一、Skywalking官网 Apache SkyWalking 1.下载Skywalking APM &#xff08;如果下载最新的&#xff0c;双击打开闪退&#xff0c;选老点的版本&#xff09; 2. 下载 Skywalking Agents 如果下载太慢&#xff0c;建议复制下载链接&#xff0c;然后用下载器下载&#xff0c;比…

Python因AI水涨船高,AIGC已经造出了一个全新的赛道 |2023中国开发者调查报告出炉

CSDN、《新程序员》在去年ChatGPT横空出世之后&#xff0c;发起了一份围绕开发者现状、人工智能和物联网、云原生、数据库、操作系统、芯片、开源的深度调查问卷&#xff0c;此问卷也融合了各个领域对生成式 AI 的应用进展&#xff0c;最终于近日正式形成一份长达 125 页的《20…

20230802-下载并安装android-studio

下载 android-studio 安装包 https://developer.android.google.cn/studio/ 安装android-studio 双击安装包 D:\Android Studio

Android Studio新版本logcat过滤说明

按包名过滤 //输入package:&#xff08;输入一个p就会有提示的&#xff09; &#xff0c;后面加上包名 比如: package:com.xal.runcontrol package:包名可以完整或者输部分包名即可 package:包名需要输完整准确 package~:正则表达式过滤 不了解正则表达式的可以参考&#…

Linux 操作系统 Red Hat Enterprise Linux 安装教程

文章目录 笔者的操作环境&#xff1a; 制作环境&#xff1a; Win32 Disk Imager 1.0.0 Windows 10 教育版 ISO&#xff1a; Red Hat Enterprise Linux 9.2 x86_64 Red Hat Enterprise Linux&#xff08;RHEL&#xff09;是一种 Linux 操作系统。安装此操作系统的难题在于&a…

docker部署jenkins且jenkins中使用docker去部署项目

docker部署jenkins且jenkins中使用docker去部署项目 1、确定版本 2.346.1是最后一个支持jdk8的 2、编写docker-compose.yml并执行 在这个目录中新增data文件夹&#xff0c;注意data是用来跟docker中的文件进行映射的 docker-compose.yml version: "3.1" service…

软件测试这个行业究竟能做到多少岁?35岁真的是一个坎?

前言 在国内&#xff0c;软件测试行业是近10多年来随着互联网的飞速发展逐步兴起来的。 随着行业的发展&#xff0c;测试市场的人才缺口也越来越大&#xff0c;能够提供的就业机会也就越来越多&#xff0c;所以很多人都意气风发地投身到测试行业之中&#xff0c;憧憬这自己在这…

K8s影响Pod调度和Deployment

5.应用升级回滚和弹性伸缩

从Spring的角度看Memcached和Redis及操作

目录 Memcached和Redis的区别 适用场景 Memcached配置使用 Redis配置使用 在SpringBoot的框架里&#xff0c;有直连Redis的SDK却没有Memcached的&#xff0c;可见相比地位。不过各有各的适应场景&#xff0c;Redis这个单线程模型确实非常强。 Memcached和Redis的区别 共同…

【JavaWeb】 三大组件之过滤器 Filter

&#x1f384;欢迎来到边境矢梦的csdn博文&#xff0c;本文主要讲解Java 中三大组件之过滤器 Filter的相关知识&#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&…

python 实现k-means聚类算法 银行客户分组画像实战(超详细,附源码)

想要数据集请点赞关注收藏后评论区留言留下QQ邮箱 k-means具体是什么这里就不再赘述&#xff0c;详情可以参见我这篇博客 k-means 问题描述&#xff1a;银行对客户信息进行采集&#xff0c;获得了200位客户的数据&#xff0c;客户特征包括以下四个1&#xff1a;社保号码 2&am…

性能调试【学习笔记】

什么是调优&#xff1f; 每执行一个Java命令&#xff0c;就分配一个JVM&#xff0c;调优时不要混淆。 根据需求进行JVM规划和预调优优化运行JVM的运行环境&#xff08;慢、卡顿&#xff09;解决JVM运行过程中出现的各种问题&#xff08;内存泄露、内存溢出OOM&#xff09; 生…

DSP定点数的概念和表示方法

1. 基本概念 (1) 计算机中定点数的三种表示方法&#xff1a;原码、补码和反码 (2) 在DSP中一般使用补码的形式来表示操作数 (3) 整型数的表示范围由DSP芯片的字长决定&#xff0c;比如16位或24位 (4) 注意&#xff0c;符号位的bit个数&#xff0c;不同类型的数以及不同的DS…

计算机是如何工作的(笔记)

目录 寄存器 操作系统 进程&#xff08;process&#xff09; CPU pcb中关于进程调度相关的属性 寄存器 用来存储数据的单位&#xff0c;是CPU的一部分 寄存器&#xff0c;存储空间更小&#xff0c;访问速度更快&#xff0c;成本更高&#xff0c;掉电后数据会丢失 寄存器…

在线协作设计工具都有哪些?推荐这10款

协作设计是一个复杂而乏味的设计过程系统&#xff0c;不仅需要许多设计师同时进行在线设计协作&#xff0c;而且还包含了许多团队角色。 因此&#xff0c;为了协同设计高质量的产品&#xff0c;更好地服务客户服务&#xff0c;选择高质量的设计协作软件已成为许多设计师的首要…

C++sokcet网络编程笔记

C网络编程 TCP/IP协议 网络介质层&#xff1a;将模拟信号转化成数字信号&#xff0c;会形成一个MAC地址&#xff08;本机地址&#xff0c;一般情况下不会变化&#xff09;。百兆宽带用4根线&#xff0c;千兆宽带用8根线进行传输。 网络层&#xff1a;进行网络层的通讯&#x…

数据结构 | 递归

目录 一、何谓递归 1.1 计算一列数之和 1.2 递归三原则 1.3 将整数转换成任意进制的字符串 二、栈帧&#xff1a;实现递归 三、递归可视化 四、谢尔平斯基三角形 五、复杂的递归问题 六、动态规划 一、何谓递归 递归是解决问题的一种办法&#xff0c;它将问题不断地分…

本地mvn仓库清理无用jar包

背景 开发java时间久了&#xff0c;本地的m2仓库就会产生很多过期的jar包&#xff0c;不清理的话比较占空间。 原理 是通过比较同一目录下&#xff0c;对应jar包的版本号的大小&#xff0c;保留最大版本号那个&#xff0c;删除其他的。 脚本 执行脚本见文章顶部 执行方式 …

P3374 【模板】树状数组 1 浅谈树状数组 (内附封面)

【模板】树状数组 1 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; 将某一个数加上 x x x 求出某区间每一个数的和 输入格式 第一行包含两个正整数 n , m n,m n,m&#xff0c;分别表示该数列数字的个数和操作的总个数。 第二…

部署安装私服-Gitlab

一、国内的gitlab是极狐 www.gitlab.cn 国服 www.github.com 国际服 二、国服的gitlab蛮适合中国国情的 1.提交申请可以获得30天的订阅版服务&#xff0c;有需要的话可以先提交一下。订阅后功能多一些。 Gitlab中文官网下载_GitLab免费下载安装_极狐GitLab免…