springboot 集成 etcd
springboot 集成 etcd
往期内容
- ETCD 简介
- docker部署ETCD
前言
好久不见各位小伙伴们,上两期内容中,我们对于分布式kv存储中间件有了简单的认识,完成了docker-compose 部署etcd集群以及可视化工具 etcd Keeper,既然有了认识,完成了部署,那么当然要用起来啦
那么本期我们简单使用springboot 集成etcd 实现一些简单的数据操作
1-创建springboot工程
对于java开发的小伙伴来说,springboot项目的创建这块,我们不在过多赘述,简单贴一下我的版本依赖,我们直接跳转至下一环节
<properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.6.13</spring-boot.version></properties>
2-集成依赖
简单的开发需要集成ETCD的依赖
那么直接pom.xml
<!-- https://mvnrepository.com/artifact/io.etcd/jetcd-core 主要依赖--><dependency><groupId>io.etcd</groupId><artifactId>jetcd-core</artifactId><version>0.7.5</version></dependency><!-- (可选依赖)-><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version><scope>provided</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.21</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.21</version></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.52</version></dependency>
3-全局配置
application.yml
#etcd
etcd:host: http://XXXXXX #你自己的宿主机port: 12379 #etcd的宿主机port 上一节中我的容器中的2379映射到了宿主机上的12379 所以配置12379
增加全局配置文件读取yml配置信息
@Configuration
@Data
public class EtcdConfig {@Value("${etcd.host}")private String etcdHost;@Value("${etcd.port}")private int etcdPort;}
创建etcd连接工厂
@Beanpublic Client etcdFactory() {return Client.builder().endpoints(etcdHost + ":" + etcdPort).build();}
4-接入使用
创建service类进行简单的操作,这里简单的存储和redis一样,也是key-value的形式,不过多赘述
对于租约lease 而言类似一redis的键设置过期时间,过期时间内可以续期,过期时间之后etcd将会删除存储的内容
package com.jerry.springetcd.service;import com.alibaba.fastjson2.JSON;
import io.etcd.jetcd.ByteSequence;
import io.etcd.jetcd.Client;
import io.etcd.jetcd.Lease;
import io.etcd.jetcd.kv.GetResponse;
import io.etcd.jetcd.kv.PutResponse;
import io.etcd.jetcd.lease.LeaseTimeToLiveResponse;
import io.etcd.jetcd.options.LeaseOption;
import io.etcd.jetcd.options.PutOption;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;@Servicepublic class EtcdService {@Resourceprivate Client etcdClient;/**** Put a key-value pair to etcd* @param key* @param value* @return*/public CompletableFuture<PutResponse> putValueWithOutLease(String key, String value) {ByteSequence keyByte = ByteSequence.from(key, StandardCharsets.UTF_8);ByteSequence valueByte = ByteSequence.from(value, StandardCharsets.UTF_8);return etcdClient.getKVClient().put(keyByte, valueByte);}/**** Get the value of a key from etcd* @param key* @return*/public CompletableFuture<String> getValue(String key) {ByteSequence keyByte = ByteSequence.from(key, StandardCharsets.UTF_8);CompletableFuture<GetResponse> getFuture = etcdClient.getKVClient().get(keyByte);return getFuture.thenApply(getResponse -> {if (getResponse.getKvs().isEmpty()) {return null;}return getResponse.getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);});}/**** Delete a key-value pair from etcd* @param key* @return*/public CompletableFuture<Void> deleteValue(String key) {ByteSequence keyByte = ByteSequence.from(key, StandardCharsets.UTF_8);return etcdClient.getKVClient().delete(keyByte).thenAccept(deleteResponse -> {});}/**** Put a key-value pair to etcd with a lease* @param key* @param value* @param leaseTime* @param timeout* @return* @throws ExecutionException* @throws InterruptedException* @throws TimeoutException*/public CompletableFuture<PutResponse> putValueWithLease(String key, String value, long leaseTime, long timeout) throws ExecutionException, InterruptedException, TimeoutException {ByteSequence keyByte = ByteSequence.from(key, StandardCharsets.UTF_8);ByteSequence valueByte = ByteSequence.from(value, StandardCharsets.UTF_8);Lease leaseClient = etcdClient.getLeaseClient();long leaseId = leaseClient.grant(leaseTime).get(timeout, TimeUnit.SECONDS).getID();System.out.println("Lease ID: " + leaseId);PutOption putOption = PutOption.newBuilder().withLeaseId(leaseId).build();// put value with leaseCompletableFuture<PutResponse> putResponse = etcdClient.getKVClient().put(keyByte, valueByte, putOption);return putResponse;}/**** 续租一个已存在的租约* @param leaseId* @return*/public CompletableFuture<Void> renewLease(long leaseId) {Lease leaseClient = etcdClient.getLeaseClient();return leaseClient.keepAliveOnce(leaseId).thenAccept(keepAliveResponse -> {if (keepAliveResponse.getTTL() == -1) {// lease has expiredSystem.out.println("Lease has expired");}else {System.out.println("Lease is renewed");}});}/**** 获取租约的信息* @param leaseId* @return*/public CompletableFuture<LeaseTimeToLiveResponse> getLeaseInfo(long leaseId) throws ExecutionException, InterruptedException {Lease leaseClient = etcdClient.getLeaseClient();LeaseTimeToLiveResponse lTRes = leaseClient.timeToLive(leaseId, LeaseOption.newBuilder().withAttachedKeys().build()).get();return CompletableFuture.completedFuture(lTRes);}
}
创建简单的controller 进行请求尝试
//存
@PostMapping("/putValueWithOutLease")public CompletableFuture<PutResponse> putValueWithOutLease(@RequestParam String key, @RequestParam String value) {return etcdService.putValueWithOutLease(key, value);}
//取
@GetMapping("/get")public CompletableFuture<String> getValueWithOutLease(@RequestParam String key) {return etcdService.getValue(key);}
//删除@DeleteMapping("/deleteValue")public CompletableFuture<Void> deleteValue(@RequestParam String key) {return etcdService.deleteValue(key);}
//带租约的存储@PostMapping("/putValueWithLease")public CompletableFuture<PutResponse> putValueWithLease(@RequestParam String key,@RequestParam String value,@RequestParam Long leaseTime,@RequestParam Long timeOut) throws ExecutionException, InterruptedException, TimeoutException {return etcdService.putValueWithLease(key, value,leaseTime, timeOut);}
//顺序存储@PutMapping("/writeWithOutLease")public String writeValue(@RequestParam int num) {logger.info("write value to etcd");StopWatch stopWatch = new StopWatch();stopWatch.start("write");for (int i = 0; i < num; i++) {etcdService.putValueWithOutLease("/test/" + i, String.valueOf(i));}stopWatch.stop();logger.info("write value to etcd, time: " + stopWatch.prettyPrint());return "success";}
//查看租约状态@PostMapping("/viewLeaseDetail")public CompletableFuture<LeaseTimeToLiveResponse> getLeaseInfo(@RequestParam Long leaseId) throws ExecutionException, InterruptedException {return etcdService.getLeaseInfo(leaseId);}
//续租@PostMapping("/renewLease")public CompletableFuture<Void> renewLease(@RequestParam long leaseId) throws ExecutionException, InterruptedException, TimeoutException {return etcdService.renewLease(leaseId);}
5-接口模拟验证
使用apipost 进行接口调用,查看执行情况
- 不带租约存储


- 不带租约查询

- 手动删除key

- 删除后重新查询,返回空值

- 带租约存储值
设置key=/acc/test val=hello etcd 租约时间为2min的数据存储


- 查询数据信息

demo gitee地址
相关文章:
springboot 集成 etcd
springboot 集成 etcd 往期内容 ETCD 简介docker部署ETCD 前言 好久不见各位小伙伴们,上两期内容中,我们对于分布式kv存储中间件有了简单的认识,完成了docker-compose 部署etcd集群以及可视化工具 etcd Keeper,既然有了认识&a…...
03_Redis基本操作
1.Redis查询命令 1.1 官网命查询命令 为了便于学习Redis,官方将其用于操作不同数据类型的命令进行了分类整理。你可以通过访问Redis官方网站上的命令参考页面https://redis.io/commands来查阅这些分组的命令,这有助于更系统地理解和使用Redis的各项功能。 1.2 HELP查询命令…...
pycharm-pyspark 环境安装
1、环境准备:java、scala、pyspark、python-anaconda、pycharm vi ~/.bash_profile export SCALA_HOME/Users/xunyongsun/Documents/scala-2.13.0 export PATH P A T H : PATH: PATH:SCALA_HOME/bin export SPARK_HOME/Users/xunyongsun/Documents/spark-3.5.4-bin…...
Unity + Firebase + GoogleSignIn 导入问题
我目前使用 Unity版本:2021.3.33f1 JDK版本为:1.8 Gradle 版本为:6.1.1 Firebase 版本: 9.6.0 Google Sign In 版本为: 1.0.1 问题1 :手机点击登录报错 apk转化成zip,解压,看到/lib/armeabi-v…...
web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理
web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理 1.uni.getSystemInfoSync().screenWidth; 获取屏幕宽度 2.uni.onWindowResize() 实时监测屏幕宽度变化 3.根据宽度的大小拿到每行要展示的数量itemsPerRow 4.为了确保样式能够根据 items…...
2025年VGC大众汽车科技社招入职测评综合能力英语口语SHL历年真题汇总、考情分析
早在1978年,大众汽车集团就开始了与中国的联系。1984年,集团在华的第一家合资企业—上汽大众汽车有限公司奠基成立;1991年,一汽-大众汽车有限公司成立;2017年,大众汽车(安徽)有限公司…...
Linux中配置Java环境变量
基本工作 1.官网下载java 1.8地址(需要注册一个oracle账户): Java Downloads | Oracle 点击上面的链接,滚动页面到最下面就可以看到下载界面,如下图 选择适合自己系统的版本。 本文选用 jdk-8u431-linux-x64.tar.g…...
完全自定义Qt翻译功能,不使用Qt Linguist的.ts 和 .qm类型翻译
这篇文章展示了集成Qt Linguist 的功能。 但是有时候Qt的翻译功能比较繁琐,我们简单项目只需要使用本地化功能,将中文字符串导入到项目中,避免编码格式问题导致的乱码。 只需要使用一个简单的json或者其他格式的本地文件作为映射的key/value.…...
551 灌溉
常规解法: #include<bits/stdc.h> using namespace std; int n,m,k,t; const int N105; bool a[N][N],b[N][N]; int cnt; //设置滚动数组来存贮当前和下一状态的条件 //处理传播扩散问题非常有效int main() {cin>>n>>m>>t;for(int i1;i&l…...
php函数性能优化中应注意哪些问题
PHP 函数性能优化中的注意事项 在 PHP 应用中优化函数性能对于提升整体运行效率至关重要。以下是一些需要注意的关键问题: 1. 避免内联变量 将变量内联到函数调用中会增加不必要的开销。例如: function sum($a, $b) {return $a $b; }// 不要这样做&…...
安科瑞 Acrel-1000DP 分布式光伏监控系统在工业厂房分布式光伏发电项目中的应用
吕梦怡 18706162527 摘 要:常规能源以煤、石油、天然气为主,不仅资源有限,而且会造成严重的大气污染,开发清洁的可再生能源已经成为当今发展的重要任务,“节能优先,效率为本”的分布式发电能源符合社会发…...
鼠标自动移动防止锁屏的办公神器 —— 定时执行专家
目录 ◆ 如何设置 ◇ 方法1:使用【执行Nircmd命令】任务 ◇ 方法2:使用【模拟键盘输入】任务 ◆ 定时执行专家介绍 ◆ 定时执行专家最新版下载 ◆ 如何设置 ◇ 方法1:使用【执行Nircmd命令】任务 1、点击工具栏第一个图标【新建任务】&…...
各种特种无人机快速发展,无人机反制技术面临挑战
随着科技的飞速发展,各种特种无人机在军事、民用等领域得到了广泛应用,其性能不断提升,应用场景也日益丰富。然而,无人机反制技术的发展确实面临一定的挑战,难以完全跟上无人机技术的快速发展步伐。以下是对这一问题的…...
深入学习RabbitMQ的Direct Exchange(直连交换机)
RabbitMQ作为一种高性能的消息中间件,在分布式系统中扮演着重要角色。它提供了多种消息传递模式,其中Direct Exchange(直连交换机)是最基础且常用的一种。本文将深入介绍Direct Exchange的原理、应用场景、配置方法以及实践案例&a…...
HTML实战课堂之启动动画弹窗
一:代码片段讲解 小提示:下面是一个包含启动页和弹窗的完整示例。这个示例包括一个简单的启动页和一个弹窗,当用户点击启动页上的按钮时,会显示弹窗。 1. **HTML结构**: - #startPage:启动页,包…...
将本地的 Git 仓库上传到 GitHub 上(github没有该仓库)
文章目录 步骤 1:在 GitHub 上创建新仓库步骤 2:配置本地仓库步骤 3:添加远程仓库地址步骤 4:推送本地代码到 GitHub验证上传 步骤 1:在 GitHub 上创建新仓库 登录 GitHub: 打开浏览器并访问 GitHub。使用自…...
【Linux】模拟Shell命令行解释器
一、知识补充 1.1 snprintf snprintf() 是 C语言的一个标准库函数,定义在<stdio.h>头文件中。 snprintf() 函数的功能是格式化字符串,并将结果存储在指定的字符数组中。该函数的原型如下: int snprintf(char *str, size_t size, con…...
G-Star Landscape 2.0 重磅发布,助力开源生态再升级
近日,备受行业瞩目的 G-Star Landscape 迎来了其 2.0 版本的发布,这一成果标志着 GitCode 在开源生态建设方面又取得了重要进展。 G-Star Landscape仓库链接: https://gitcode.com/GitCode-official-team/G-Star-landscape 2024 GitCode 开…...
Lianwei 安全周报|2024.1.7
以下是本周「Lianwei周报」,我们总结推荐了本周的政策/标准/指南最新动态、热点资讯和安全事件,保证大家不错过本周的每一个重点! 政策/标准/指南最新动态 01 国家发改委等三部门印发《国家数据基础设施建设指引》 国家数据基础设施是从数据…...
ASP.NET Core 实现微服务 - Consul 配置中心
这一次我们继续介绍微服务相关组件配置中心的使用方法。本来打算介绍下携程开源的重型配置中心框架 apollo 但是体系实在是太过于庞大,还是让我爱不起来。因为前面我们已经介绍了使用Consul 做为服务注册发现的组件 ,那么干脆继续使用 Consul 来作为配置…...
TFLI2C库详解:Benewake TFLuna激光测距传感器的I²C驱动开发指南
1. TFLI2C 库概述:面向 Benewake TFLuna 的专用 IC 驱动框架TFLI2C 是一个专为 Benewake TFLuna 激光测距传感器设计的 Arduino 兼容库,其核心目标是通过标准 IC(Inter-Integrated Circuit)总线实现对设备的高可靠性、低开销控制与…...
北京交通大学 | 基于TD3算法的层叠超表面辅助多用户MISO系统联合优化研究
引言随着无线通信技术的不断发展,可重构智能表面(RIS)技术因其低功耗和信号操控能力而受到广泛关注。然而,RIS的单层结构和离散相移能力限制了其性能表现。层叠智能超表面(SIM)作为一项创新技术,…...
XZ8011双节8.4V充电芯片 输入电压8.9-15V
XZ8011是一款完整的双节锂离子电池恒压恒流充电管理芯片。采用ESOP8封装形式,外加很少的外部元件,使其成为便携应用的理想选择。 XZ8011通过外接电流检测电阻即可实现高精度的充电电流。其内部有热反馈电路可以对在充电过程中对芯片温度加以控制。充电截…...
V821 DISP 显示驱动流程分析
文章目录1、前言2、环境介绍3、大致流程4、程序阅读5、总结1、前言 在全志 V821 下调试 RGB 屏幕时,因为一直创建不出 fb 节点,这里记录一下当时阅读显示驱动框架的过程。仅供参考。 2、环境介绍 sdk:V821 tina sdk v1.3 3、大致流程 初…...
OFA图像描述系统实战:快速搭建图片转文字工具,避免常见权限错误
OFA图像描述系统实战:快速搭建图片转文字工具,避免常见权限错误 1. 项目介绍:让图片自己“说话”的智能工具 你有没有遇到过这样的场景?手头有一堆产品图片,需要为每张图配上文字描述,手动编写不仅耗时耗…...
118. 从 RKE1(Docker)迁移到 RKE2(容器化)后,JSON 日志未能正确解析
Situation 地理位置After migrating the cluster from RKE1 to RKE2, JSON logs sent to Elasticsearch are not being split into fields correctly. 在将集群从 RKE1 迁移到 RKE2 后,发送到 Elasticsearch 的 JSON 日志没有被正确划分为字段。 Resolution 结局T…...
多目标跟踪算法实战:从DeepSORT到Chained-Tracker的避坑指南
多目标跟踪算法实战:从DeepSORT到Chained-Tracker的避坑指南 在计算机视觉领域,多目标跟踪(Multi-Object Tracking, MOT)技术正逐渐从实验室走向工业界。不同于学术论文中那些理想化的测试场景,真实项目中的光照变化、遮挡干扰和计算资源限制…...
保姆级教程:用国产龙虾AiPy自己打造全链路写文到一键发布
近期在探索 AI 自动化办公场景,尝试通过智能体工具自主构建功能插件,实现从内容创作、图文排版到公众号上传发布的全流程自动化,同时搭配远程控制功能,实现户外离线指令触发、电脑端自动执行,大幅降低自媒体日更的操作…...
当测试脚本杀人:军工AI系统的质量失控实录
对于软件测试从业者而言,我们早已习惯了与代码缺陷、性能瓶颈和逻辑错误作斗争。我们构建自动化脚本,设计测试用例,守护着软件世界的秩序与安全。然而,当测试的对象从商业应用转向决定生死的军工AI系统时,质量保障的维…...
实战指南:基于快马AI生成代码,快速构建并部署一个完整企业网站
今天想和大家分享一个实战经验:如何用InsCode(快马)平台快速搭建一个完整的企业网站。整个过程非常流畅,特别适合需要快速上线展示页面的场景。 项目结构规划 首先明确企业网站需要的核心页面:首页、关于我们、服务项目、案例展示、团队介绍、…...
