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获取配置,并且对配置的变化进行监控的更多相关文章

  1. Java中的微信支付(2):API V3 微信平台证书的获取与刷新

    1. 前言 在Java中的微信支付(1):API V3版本签名详解一文中胖哥讲解了微信支付V3版本API的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API证书对参数进行加签,微信 ...

  2. Java中的微信支付(1):API V3版本签名详解

    1. 前言 最近在折腾微信支付,证书还是比较烦人的,所以有必要分享一些经验,减少你在开发微信支付时的踩坑.目前微信支付的API已经发展到V3版本,采用了流行的Restful风格. 今天来分享微信支付的 ...

  3. Java中的微信支付(3):API V3对微信服务器响应进行签名验证

    1. 前言 牢记一句话:公钥加密,私钥解密:私钥加签,公钥验签. 微信支付V3版本前两篇分别讲了如何对请求做签名和如何获取并刷新微信平台公钥,本篇将继续展开如何对微信支付响应结果的验签. 2. 为什么 ...

  4. java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。

    首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一.  类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...

  5. Java中校验身份证号合法性(真伪),获取出生日期、年龄、性别、籍贯

    开发过程中有用的身份证号的业务场景,那么校验身份证的合法性就很重要了,另外还有通过身份证获取出生日期.年龄.性别.籍贯等信息, 下面是本人在开发中用到的关于校验身份证真伪的工具类,可以直接拿来使用,非 ...

  6. 在Autodesk Vault 2014中使用VDF(Vault Development Framework) API获取所有文件的属性信息

      这几天在玩儿Vault API, 从Autodesk Vault 2014开始提供了Vault Development Framework(VDF) API,让开发工作更简单了.在Vault 20 ...

  7. 第89节:Java中的反射技术

    第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...

  8. 第76节:Java中的基础知识

    第76节:Java中的基础知识 设置环境,安装操作系统,安装备份,就是镜像,jdk配置环境,eclipse下载解压即可使用,下载tomcat 折佣动态代理解决网站的字符集编码问题 使用request. ...

  9. java中的日志打印

    java中的日志打印: 日志工具类: #获取日志 INFO:表示获取日志的等级 A1:表示日志存器,可以自定义名称 #===DEBUG INFO log4j.rootLogger=DEBUG,A1,A ...

随机推荐

  1. Django之中间件

    中间件简介 什么是中间件 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的功 ...

  2. python实现归并排序,归并排序的详细分析。

    学习归并排序的过程是十分痛苦的.它并不常用,看起来时间复杂度好像是几种排序中最低的,比快排的时间复杂度还要低,但是它的执行速度不是最快的.很多朋友不理解时间复杂度低为什么运行速度不一定快,这个不清楚的 ...

  3. netty学习--handler传递

    在netty中的处理链pipeline中,事件是按顺序传递的,把自己拟人为netty程序,针对进来(inbound)的请求,会从head开始,依次往tail传递. pipeline采用了链表结构,he ...

  4. mysql 存储过程 实现数据同步

    数据库 表 发生变化,需要把2.0的表数据 同步到3.0库中去: -- 同步数据存储过程执行 -- 更新留言旧表数据到新表数据中 /*DEFINER:Vector*/ drop procedure i ...

  5. Windows10+Docker搭建分布式Redis集群(一)

    摘要,Docker for Windows 仅支持专业版 目录 第一步:检查系统支持虚拟化 第二步:下载Docker对应版本 第三步:配置镜像加速 第一步:检查系统是否支持虚拟化 Docker前提是需 ...

  6. SpringMVC(九):SpringMVC 处理输出模型数据之ModelAndView

    Spring MVC提供了以下几种途径输出模型数据: 1)ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据: 2)Map及Model:处理方法 ...

  7. c# IPC实现本机进程之间的通信

    IPC可以实现本地进程之间通信.这种用法不是太常见,常见的替代方案是使用wcf,remoting,web service,socket(tcp/pipe/...)等其他分布式部署方案来替代进程之间的通 ...

  8. Java面试题—初级(3)

    21.ArrayList和Vector的区别 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态 ...

  9. ORACLE数据库编程

    第一章 Oracle数据库基本概念 一.介绍 Oracle数据库系统是美国Oracle(甲骨文)公司提供的以分布式数据库为 核心的一组软件产品,是目前最流行的客户/服务器(Client/Server, ...

  10. jacascript 原生选项卡插件

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 在布局的时候,想到了很多以前看到过的案例,再次熟悉一下: a链接之间的竖线:可以用a链接的border-r ...