etcd 和zookeeper 很像,都可以用来做配置管理。并且etcd可以在目前流行的Kubernetes中使用。
但是etcd 提供了v2版本合v3的版本的两种api。我们现在分别来介绍一下这两个版本api的使用。
一、Etcd V2版本API
1、java工程中使用maven引入 etcd v2的java api操作jar包
io.netty
netty-all
4.1.21.Final
org.mousio
etcd4j
2.15.0
2、etcd的链接
importmousio.etcd4j.EtcdClient;importjava.io.InputStream;importjava.net.URI;importjava.util.Properties;public classEtcdUtil {//etcd客户端链接
private static EtcdClient client = null;//链接初始化
public static synchronizedEtcdClient getClient(){if (null ==client){
client= new EtcdClient (URI.create(properties.getProperty("http://127.0.0.1:2379")));
}returnclient;
}
}
3、如何获取etcd的配置并且对配置进行监听
//初始化获取etcd配置并且进行配置监听
private voidinitEtcdConfig() {
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();
}
}privateString 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)){returnnode.getValue();
}
}
}
System.out.println("Etcd configFile"+ configFile+"is not exist,Please Check");return null;
}public voidstartListenerThread(EtcdClient etcdClient){new Thread(()->{
startListener(etcdClient);
}).start();
}public voidstartListener(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,项目的地址:
二、Etcd V3版本API
1、在工程引入如下依赖
io.netty
netty-all
4.1.15.Final
com.coreos
jetcd-core
0.0.2
2、v3 api操作工具类
public classEtcdUtil {//etcl客户端链接
private static Client client = null;//链接初始化
public static synchronizedClient getEtclClient(){if(null ==client){
client= Client.builder().endpoints(props.getProperty("http://127.0.0.1:2379")).build();
}returnclient;
}/*** 根据指定的配置名称获取对应的value
*@paramkey 配置项
*@return*@throwsException*/
public static String getEtcdValueByKey(String key) throwsException {
List kvs =EtcdUtil.getEtclClient().getKVClient().get(ByteSequence.fromString(key)).get().getKvs();if(kvs.size()>0){
String value= kvs.get(0).getValue().toStringUtf8();returnvalue;
}else{return null;
}
}/*** 新增或者修改指定的配置
*@paramkey
*@paramvalue
*@return
*/
public static void putEtcdValueByKey(String key,String value) throwsException{
EtcdUtil.getEtclClient().getKVClient().put(ByteSequence.fromString(key),ByteSequence.fromBytes(value.getBytes("utf-8")));
}/*** 删除指定的配置
*@paramkey
*@return
*/
public static voiddeleteEtcdValueByKey(String key){
EtcdUtil.getEtclClient().getKVClient().delete(ByteSequence.fromString(key));
}
}//V3 api配置初始化和监听
public voidinit(){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(Listkvs){if(kvs.size()>0){
String config= kvs.get(0).getValue().toStringUtf8();
System.out.println("etcd 's config 's configValue is :"+config);returnconfig;
}else{return null;
}
}
v3版本的正式版本代码(可以直接使用的工具类,并且加上了日志):
1 importcom.coreos.jetcd.Client;2 importcom.coreos.jetcd.Watch;3 importcom.coreos.jetcd.data.ByteSequence;4 importcom.coreos.jetcd.data.KeyValue;5 importorg.slf4j.Logger;6 importorg.slf4j.LoggerFactory;7 importjava.util.List;8 /**
9 * etcd 链接和操作工具,包括启动监听 操作etcd v3 版本协议,此操作不支持v2 版本协议。10 * v2版本的协议可以参考https://www.cnblogs.com/laoqing/p/8967549.html
11 */
12 public classEtcdUtil {13 public static Logger log = LoggerFactory.getLogger(EtcdUtil.class);14 //etcl客户端链接
15 private static Client client = null;16
17 //链接初始化 单例模式
18 public static synchronizedClient getEtclClient(){19 if(null ==client){20 client = Client.builder().endpoints("http://xxx.xxx.xxx.xxx:2379").build();21 }22 returnclient;23 }24 /**
25 * 根据指定的配置名称获取对应的value26 *@paramkey 配置项27 *@return
28 *@throwsException29 */
30 public static String getEtcdValueByKey(String key) throwsException {31 List kvs =EtcdUtil.getEtclClient().getKVClient().get(ByteSequence.fromString(key)).get().getKvs();32 if(kvs.size()>0){33 String value = kvs.get(0).getValue().toStringUtf8();34 returnvalue;35 }36 else{37 return null;38 }39 }40 /**
41 * 新增或者修改指定的配置42 *@paramkey43 *@paramvalue44 *@return
45 */
46 public static void putEtcdValueByKey(String key,String value) throwsException{47 EtcdUtil.getEtclClient().getKVClient().put(ByteSequence.fromString(key),ByteSequence.fromBytes(value.getBytes("utf-8")));48 }49 /**
50 * 删除指定的配置51 *@paramkey52 *@return
53 */
54 public static voiddeleteEtcdValueByKey(String key){55 EtcdUtil.getEtclClient().getKVClient().delete(ByteSequence.fromString(key));56 }57 /**
58 * etcd的监听,监听指定的key,当key 发生变化后,监听自动感知到变化。59 *@paramkey 指定需要监听的key60 */
61 public static voidinitListen(String key){62 try{63 //加载配置
64 getConfig(EtcdUtil.getEtclClient().getKVClient().get(ByteSequence.fromString(key)).get().getKvs());65 new Thread(() ->{66 Watch.Watcher watcher =EtcdUtil.getEtclClient().getWatchClient().watch(ByteSequence.fromString(key));67 try{68 while(true) {69 watcher.listen().getEvents().stream().forEach(watchEvent ->{70 KeyValue kv =watchEvent.getKeyValue();71 log.info("etcd event:{} ,change key is:{},afterChangeValue:{}",watchEvent.getEventType(),kv.getKey().toStringUtf8(),kv.getValue().toStringUtf8());72 });73 }74 } catch(InterruptedException e) {75 log.info("etcd listen start cause Exception:{}",e);76 }77 }).start();78 } catch(Exception e) {79 log.info("etcd listen start cause Exception:{}",e);80 }81 }82 private static String getConfig(Listkvs){83 if(kvs.size()>0){84 String config = kvs.get(0).getKey().toStringUtf8();85 String value = kvs.get(0).getValue().toStringUtf8();86 log.info("etcd 's config 's config key is :{},value is:{}",config,value);87 returnvalue;88 }89 else{90 return null;91 }92 }93 }
运行后的效果:
另外v3 版本api 的管理界面,可以参考如下开源项目
【原文归作者所有,欢迎转载,但是保留版权,并且转载时,需要注明出处】