问题描述
最近公司在做自己的配置中心,其实就是在apllo的基础上加了一层封装,现有如下一个需求:
比如我配置100台服务器,都用了配置中心,但是我如果修改了配置中心的配置,我如何知道这100台服务器都生效了。
实现方案
由于配置中心的配置会存放在本地缓存一份,所以读取本地配置,将这些配置进行排序,
然后用md5加密,将ip和MD5存放数据库,查询作比较即可。
监听apollo配置,获取配置MD5
Config config = ConfigService.getConfig(namespaces);
config.addChangeListener(changeEvent -> {
configService.updConfigMD5ByIp();
});
@Value("${apollo.config-cache-path}")
private String configCachePath;
public void updConfigMD5ByIp(){
try {
InetAddress localHost = InetAddress.getLocalHost();
String hostAddress = localHost.getHostAddress();
String md5 = MD5Util.getMD5Checksum(configCachePath);
System.out.println(hostAddress + "----------" + md5);
ConfigMD5Info configMD5Info = configMD5Dao.selectConfigMD5ByIp(hostAddress);
if(configMD5Info == null){
configMD5Info = new ConfigMD5Info();
configMD5Info.setConfigMD5(md5);
configMD5Info.setIp(hostAddress);
configMD5Dao.insertConfigMD5(configMD5Info);
}else{
configMD5Info.setConfigMD5(md5);
configMD5Dao.updateConfigMD5(configMD5Info);
}
} catch (Exception e) {
log.info("根据IP地址修改MD5配置出错" , e);
}
}
package com.formssi.gateway.util;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@Slf4j
public class MD5Util {
private static byte[] createChecksum(String filename) {
InputStream fis = null;
try {
fis = new FileInputStream(filename);
MessageDigest complete = MessageDigest.getInstance("MD5");
String aLine;
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
ArrayList<String> al = new ArrayList<String> ();
while ((aLine = in.readLine()) != null) {
if (!aLine.trim().startsWith("#") && aLine.trim().length() > 0) {
al.add(aLine);
}
}
Collections.sort(al, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return arrangeStringsAccordingToAscii(o1, o2);
}
});
StringBuilder sb = new StringBuilder();
al.stream().forEach(item -> {
sb.append(item);
});
return complete.digest(sb.toString().getBytes());
} catch (FileNotFoundException e) {
log.info(e.getMessage());
} catch (NoSuchAlgorithmException e) {
log.info(e.getMessage());
} catch (IOException e) {
log.info(e.getMessage());
} finally {
try {
if (null != fis) {
fis.close();
}
} catch (IOException e) {
}
}
return null;
}
private static int arrangeStringsAccordingToAscii(String firstText, String lastText) {
char[] firstChars = firstText.toCharArray();
char[] lastChars = lastText.toCharArray();
int min = Math.min(firstChars.length, lastChars.length);
for (int index = 0; index < min; index++) {
if (firstChars[index] > lastChars[index]) {
return 1;
} else if (firstChars[index] < lastChars[index]) {
return -1;
}
}
return firstChars.length - lastChars.length;
}
public static String getMD5Checksum(String filename) {
if (!new File(filename).isFile()) {
log.info("Error: " + filename + " is not a valid file.");
return null;
}
byte[] b = createChecksum(filename);
if (null == b) {
log.info("Error:create md5 string failure!");
return null;
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < b.length; i++) {
result.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));
}
return result.toString();
}
}
注:apollo本地文件缓存目录是可配的,我用的是默认的配置目录,网上有很多配置地址的文章,这里就就不做阐述了