在java中如何使用etcd的v2 和v3 api获取配置,并且对配置的变化进行监控
etcd 和zookeeper 很像,都可以用来做配置管理。并且etcd可以在目前流行的Kubernetes中使用。
但是etcd 提供了v2版本合v3的版本的两种api。我们现在分别来介绍一下这两个版本api的使用。
一、Etcd V2版本API
1、java工程中使用maven引入 etcd v2的java api操作jar包
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.21.Final</version>
</dependency>
<dependency>
<groupId>org.mousio</groupId>
<artifactId>etcd4j</artifactId>
<version>2.15.0</version>
</dependency> 2、etcd的链接
import mousio.etcd4j.EtcdClient;
import java.io.InputStream;
import java.net.URI;
import java.util.Properties; public class EtcdUtil {
//etcd客户端链接
private static EtcdClient client = null;
//链接初始化
public static synchronized EtcdClient getClient(){
if (null == client){
client = new EtcdClient (URI.create(properties.getProperty("http://127.0.0.1:2379")));
}
return client;
}
}
3、如何获取etcd的配置并且对配置进行监听
//初始化获取etcd配置并且进行配置监听
private void initEtcdConfig() {
EtcdKeysResponse dataTree ;
try {
final EtcdClient etcdClient = EtcdUtil.getClient();
//获取etcd中名称叫ETCD文件夹下的配置
EtcdKeyGetRequest etcdKeyGetRequest = etcdClient.getDir("ETCD").consistent();
dataTree = etcdKeyGetRequest.send().get();
//获取etcd的版本
System.out.println("ETCD's version:"+etcdClient.getVersion());
getConfig("/ETCD/example.config",dataTree); //加载配置项
//启动一个线程进行监听
startListenerThread(etcdClient);
} catch (Exception e) {
System.out.println("EtcdClient init cause Exception:"+e.getMessage());
e.printStackTrace();
}
}
private String getConfig(String configFile,EtcdKeysResponse dataTree){
if(null != dataTree && dataTree.getNode().getNodes().size()>0){
for(EtcdKeysResponse.EtcdNode node:dataTree.getNode().getNodes()){
if(node.getKey().equals(configFile)){
return node.getValue();
}
}
}
System.out.println("Etcd configFile"+ configFile+"is not exist,Please Check");
return null;
}
public void startListenerThread(EtcdClient etcdClient){
new Thread(()->{
startListener(etcdClient);
}).start();
}
public void startListener(EtcdClient etcdClient){
ResponsePromise promise =null;
try {
promise = etcdClient.getDir(SYSTEM_NAME).recursive().waitForChange().consistent().send();
promise.addListener(promisea -> {
System.out.println("found ETCD's config cause change");
try {
getConfig("/ETCD/example.config", etcdClient.getDir("ETCD").consistent().send().get()); //加载配置项
} catch (Exception e) {
e.printStackTrace();
System.out.println("listen etcd 's config change cause exception:{}"+e.getMessage());
}
startListener(etcdClient);
});
} catch (Exception e) {
startListener(etcdClient);
System.out.println("listen etcd 's config change cause exception:"+e.getMessage());
e.printStackTrace();
}
}
4、使用dcmp管理 etcd的配置项
dcmp 是一个使用go语言开发的etcd配置界面,不足的时,这个只支持v2的API,项目的地址:
https://github.com/silenceper/dcmp

二、Etcd V3版本API
1、在工程引入如下依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.15.Final</version>
</dependency>
<dependency>
<groupId>com.coreos</groupId>
<artifactId>jetcd-core</artifactId>
<version>0.0.2</version>
</dependency>
2、v3 api操作工具类
public class EtcdUtil {
//etcl客户端链接
private static Client client = null;
//链接初始化
public static synchronized Client getEtclClient(){
if(null == client){
client = Client.builder().endpoints(props.getProperty("http://127.0.0.1:2379")).build();
}
return client;
}
/**
* 根据指定的配置名称获取对应的value
* @param key 配置项
* @return
* @throws Exception
*/
public static String getEtcdValueByKey(String key) throws Exception {
List<KeyValue> kvs = EtcdUtil.getEtclClient().getKVClient().get(ByteSequence.fromString(key)).get().getKvs();
if(kvs.size()>0){
String value = kvs.get(0).getValue().toStringUtf8();
return value;
}
else {
return null;
}
}
/**
* 新增或者修改指定的配置
* @param key
* @param value
* @return
*/
public static void putEtcdValueByKey(String key,String value) throws Exception{
EtcdUtil.getEtclClient().getKVClient().put(ByteSequence.fromString(key),ByteSequence.fromBytes(value.getBytes("utf-8")));
}
/**
* 删除指定的配置
* @param key
* @return
*/
public static void deleteEtcdValueByKey(String key){
EtcdUtil.getEtclClient().getKVClient().delete(ByteSequence.fromString(key));
}
}
//V3 api配置初始化和监听
public void init(){
try {
//加载配置
getConfig(EtcdUtil.getEtclClient().getKVClient().get(ByteSequence.fromString(ETCD_CONFIG_FILE_NAME)).get().getKvs());
//启动监听线程
new Thread(() -> {
//对某一个配置进行监听
Watch.Watcher watcher = EtcdUtil.getEtclClient().getWatchClient().watch(ByteSequence.fromString("etcd_key"));
try {
while(true) {
watcher.listen().getEvents().stream().forEach(watchEvent -> {
KeyValue kv = watchEvent.getKeyValue();
//获取事件变化类型
System.out.println(watchEvent.getEventType());
//获取发生变化的key
System.out.println(kv.getKey().toStringUtf8());
//获取变化后的value
String afterChangeValue = kv.getValue().toStringUtf8();
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
private String getConfig(List<KeyValue> kvs){
if(kvs.size()>0){
String config = kvs.get(0).getValue().toStringUtf8();
System.out.println("etcd 's config 's configValue is :"+config);
return config;
}
else {
return null;
}
}
v3版本的正式版本代码(可以直接使用的工具类,并且加上了日志):
import com.coreos.jetcd.Client;
import com.coreos.jetcd.Watch;
import com.coreos.jetcd.data.ByteSequence;
import com.coreos.jetcd.data.KeyValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* etcd 链接和操作工具,包括启动监听 操作etcd v3 版本协议,此操作不支持v2 版本协议。
* v2版本的协议可以参考 https://www.cnblogs.com/laoqing/p/8967549.html
*/
public class EtcdUtil {
public static Logger log = LoggerFactory.getLogger(EtcdUtil.class);
//etcl客户端链接
private static Client client = null; //链接初始化 单例模式
public static synchronized Client getEtclClient(){
if(null == client){
client = Client.builder().endpoints("http://xxx.xxx.xxx.xxx:2379").build();
}
return client;
}
/**
* 根据指定的配置名称获取对应的value
* @param key 配置项
* @return
* @throws Exception
*/
public static String getEtcdValueByKey(String key) throws Exception {
List<KeyValue> kvs = EtcdUtil.getEtclClient().getKVClient().get(ByteSequence.fromString(key)).get().getKvs();
if(kvs.size()>0){
String value = kvs.get(0).getValue().toStringUtf8();
return value;
}
else {
return null;
}
}
/**
* 新增或者修改指定的配置
* @param key
* @param value
* @return
*/
public static void putEtcdValueByKey(String key,String value) throws Exception{
EtcdUtil.getEtclClient().getKVClient().put(ByteSequence.fromString(key),ByteSequence.fromBytes(value.getBytes("utf-8")));
}
/**
* 删除指定的配置
* @param key
* @return
*/
public static void deleteEtcdValueByKey(String key){
EtcdUtil.getEtclClient().getKVClient().delete(ByteSequence.fromString(key));
}
/**
* etcd的监听,监听指定的key,当key 发生变化后,监听自动感知到变化。
* @param key 指定需要监听的key
*/
public static void initListen(String key){
try {
//加载配置
getConfig(EtcdUtil.getEtclClient().getKVClient().get(ByteSequence.fromString(key)).get().getKvs());
new Thread(() -> {
Watch.Watcher watcher = EtcdUtil.getEtclClient().getWatchClient().watch(ByteSequence.fromString(key));
try {
while(true) {
watcher.listen().getEvents().stream().forEach(watchEvent -> {
KeyValue kv = watchEvent.getKeyValue();
log.info("etcd event:{} ,change key is:{},afterChangeValue:{}",watchEvent.getEventType(),kv.getKey().toStringUtf8(),kv.getValue().toStringUtf8());
});
}
} catch (InterruptedException e) {
log.info("etcd listen start cause Exception:{}",e);
}
}).start();
} catch (Exception e) {
log.info("etcd listen start cause Exception:{}",e);
}
}
private static String getConfig(List<KeyValue> kvs){
if(kvs.size()>0){
String config = kvs.get(0).getKey().toStringUtf8();
String value = kvs.get(0).getValue().toStringUtf8();
log.info("etcd 's config 's config key is :{},value is:{}",config,value);
return value;
}
else {
return null;
}
}
}
运行后的效果:

另外v3 版本api 的管理界面,可以参考如下开源项目
https://github.com/shiguanghuxian/etcd-manage



【原文归作者所有,欢迎转载,但是保留版权,并且转载时,需要注明出处】
在java中如何使用etcd的v2 和v3 api获取配置,并且对配置的变化进行监控的更多相关文章
- Java中的微信支付(2):API V3 微信平台证书的获取与刷新
1. 前言 在Java中的微信支付(1):API V3版本签名详解一文中胖哥讲解了微信支付V3版本API的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API证书对参数进行加签,微信 ...
- Java中的微信支付(1):API V3版本签名详解
1. 前言 最近在折腾微信支付,证书还是比较烦人的,所以有必要分享一些经验,减少你在开发微信支付时的踩坑.目前微信支付的API已经发展到V3版本,采用了流行的Restful风格. 今天来分享微信支付的 ...
- Java中的微信支付(3):API V3对微信服务器响应进行签名验证
1. 前言 牢记一句话:公钥加密,私钥解密:私钥加签,公钥验签. 微信支付V3版本前两篇分别讲了如何对请求做签名和如何获取并刷新微信平台公钥,本篇将继续展开如何对微信支付响应结果的验签. 2. 为什么 ...
- java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。
首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一. 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...
- Java中校验身份证号合法性(真伪),获取出生日期、年龄、性别、籍贯
开发过程中有用的身份证号的业务场景,那么校验身份证的合法性就很重要了,另外还有通过身份证获取出生日期.年龄.性别.籍贯等信息, 下面是本人在开发中用到的关于校验身份证真伪的工具类,可以直接拿来使用,非 ...
- 在Autodesk Vault 2014中使用VDF(Vault Development Framework) API获取所有文件的属性信息
这几天在玩儿Vault API, 从Autodesk Vault 2014开始提供了Vault Development Framework(VDF) API,让开发工作更简单了.在Vault 20 ...
- 第89节:Java中的反射技术
第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...
- 第76节:Java中的基础知识
第76节:Java中的基础知识 设置环境,安装操作系统,安装备份,就是镜像,jdk配置环境,eclipse下载解压即可使用,下载tomcat 折佣动态代理解决网站的字符集编码问题 使用request. ...
- java中的日志打印
java中的日志打印: 日志工具类: #获取日志 INFO:表示获取日志的等级 A1:表示日志存器,可以自定义名称 #===DEBUG INFO log4j.rootLogger=DEBUG,A1,A ...
随机推荐
- mongodb聚合的使用
聚合: 主要用于计算和统计等,类似sql种的sum() avg() db.集合.aggregate( { 管道:{表达式} } ) 常用的管道: $group:将集合中的文档按照字段进行分组 $mat ...
- vue.js+socket.io+express+mongodb打造在线聊天[二]
vue.js+socket.io+express+mongodb打造在线聊天[二] 在线地址观看 http://www.chenleiming.com github地址 https://github. ...
- ehcache.xml 属性大全
属性大全 name:缓存名称. maxElementsInMemory:缓存最大个数. eternal:对象是否永久有效,一但设置了,timeout将不起作用. timeToIdleSeconds:设 ...
- SQL基础-----DDL
1 (My)SQL入门 这里用了(My)SQL这样的标题,目的是介绍标准SQL的同时,也将MySQL在标准SQL上的扩展一同介绍给读者. 2:SQL分类 SQL语句主要可以划分为以下3个类别 .DDL ...
- C++ 前期准备
在线编译网站: http://www.dooccn.com/cpp/ 刷题: https://leetcode.com/ https://leetcode-cn.com/
- 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池)
一.本文产生原由: 之前文章<总结消息队列RabbitMQ的基本用法>已对RabbitMQ的安装.用法都做了详细说明,而本文主要是针对在高并发且单次从RabbitMQ中消费消息时,出现了连 ...
- 《linux 网络日志分析与流量监控》记录
mac中有个本机连接vpn的日志,/private/var/log/ppp.log 消除日志(echo "" >/private/var/log/ppp.log ) li ...
- [SCOI 2012]滑雪与时间胶囊
Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi. ...
- USACO 2017 US Open
只会做T1,FallDream T2 n^2暴力AC,太强啦. T1.Modern Art 题目大意:有一个n*n的矩阵,一开始都是0,你有n^2种颜色,编号1到n^2,每次可以选出一种颜色涂满一个子 ...
- hdu 5314 动态树
Happy King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tot ...