consul中的yml配置持久化到MongoDB
作者:互联网
设计思路:
1. 获取到consul中的配置文件内容;
通过consul的官网查看consul对外提供的RESTAPI,找到获取consul中所有配置文件的名称接口;找到根据配置文件名称获取配置文件内容的接口;
2. 保存到数据库中;
通过mongoTemplate操作MongoDB数据库;每次配置文件修改后保存的时候在mongo表里新增一条数据;
3. 保存之前判断当前版本和数据库版本是否一致;
mongo数据库里存储当前版本的hash值,如果新版本的hash值和当前版本的hash值一致就放弃本次保存操作,视为配置没有改动,保留原来版本;
4. 保留20个版本;
新版本插入之前获取当前版本编号,如果当前没有版本则插入到第一个版本;如果当前有版本和当前版本号小于20则插入到当前最大版本+1的版本;如果当前版本=20在则删除第1个版本,之后每个版本递减1,新版本插入到第20版本;
废话不多说,先上代码
1. 调用 consul提供的RESTAPI接口的读取配置;
2. @Autowired
private RestTemplate restTemplate;
@Override
public String readConsul(String url, String ymlName, String token) {
try {
String reqJsonStr;
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("text/html; charset=UTF-8");
headers.setContentType(type);
headers.set("X-Consul-Token", token);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<String> exchange = restTemplate.exchange(new URI(url + ymlName), HttpMethod.GET, entity, String.class);
String result = exchange.getBody();
List<RestGetResultDo> conList = JSON.parseArray(result, RestGetResultDo.class);
return conList.get(0).getValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
3. 获取consul中所有yml名称接口
4. @Override
public List<String> getConsulConfigYmlNameList(String url, String token) {
RestTemplate restTemplate2 = new RestTemplate();
try {
String reqJsonStr;
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("text/html; charset=UTF-8");
headers.setContentType(type);
headers.set("X-Consul-Token", token);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<String> exchange = restTemplate.exchange(new URI(url), HttpMethod.GET, entity, String.class);
String result = exchange.getBody();
result = result.replaceAll("\r|\n| |\\[|\\]|\\\"", "");
String[] split = result.split(",");
return Arrays.asList(split);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
3.consul同步到mongoDB接口
public static final String VERSION_NUMBER = "versionNumber";
public static final int MAX_VERSION = 20;
@Autowired
private ConsulConfigManage consulConfigManage;
@Autowired
private MongoTemplate mongoTemplate;
@Autowired
private ConsulProperties consulProperties;
@Value("${spring.cloud.consul.token}")
private String consulToken;
/**
* consul配置持久化到MongoDB的实现类
*
* @return
*/
@Override
public Boolean consulToMongoDB() {
int versionNumber = 1;
int oldFirstDocumentHash = 1;
int newDocumentHash = 1;
boolean isSync = false;
try {
ConsulConfigDo configDo = new ConsulConfigDo();
//获取到所有配置文件的名称
List<String> consulConfigYmlNameList = consulConfigManage.getConsulConfigYmlNameList("http://" + consulProperties.getHost() + ":" + consulProperties.getPort() + "/v1/kv/" + "?keys", consulToken);
//把每个配置文件的name和content放到map中
Map map = new HashMap();
for (String ymlName : consulConfigYmlNameList) {
String ymlContent = consulConfigManage.readConsul("http://" + consulProperties.getHost() + ":" + consulProperties.getPort() + "/v1/kv/", ymlName, consulToken);
ymlName = ymlName.contains(".") ? ymlName = ymlName.substring(0, ymlName.indexOf(".")) : ymlName;
map.put(ymlName, ymlContent);
}
//查询MongoDB中最近添加的一个版本
List<ConsulConfigDo> consulConfigDos = mongoTemplate.find(new Query().with(new Sort(new Sort.Order(Sort.Direction.DESC, "_id"))), ConsulConfigDo.class);
ConsulConfigDo first = null;
//初始版本
if (consulConfigDos.size() == 0) {
configDo.set_id(System.currentTimeMillis());
configDo.setConsul_content(map);
configDo.setVersionNumber(String.format("%02d", versionNumber));
configDo.setHash(hash(configDo.getConsul_content()));
mongoTemplate.insert(configDo);
isSync = true;
} else {
first = consulConfigDos.get(0);
//最近添加的一个版本hash
oldFirstDocumentHash = first.getHash();
configDo.setConsul_content(map);
newDocumentHash = hash(configDo.getConsul_content());
if (newDocumentHash == oldFirstDocumentHash) {
//不同步
return isSync;
} else {
//同步
String versionNumber1 = first.getVersionNumber();
Integer integer = Integer.valueOf(versionNumber1);
//如果数据小于20
if (integer < MAX_VERSION) {
versionNumber = integer + 1;
} else {
//删掉第一条数据
mongoTemplate.remove(new Query(Criteria.where(VERSION_NUMBER).is("01")), ConsulConfigDo.class);
//每条数据的versionNumber递减1
List<ConsulConfigDo> documents = mongoTemplate.find(new Query().with(new Sort(new Sort.Order(Sort.Direction.ASC, "_id"))), ConsulConfigDo.class);
for (ConsulConfigDo document : documents) {
Integer versionNum = Integer.valueOf(document.getVersionNumber());
String format = String.format("%02d", versionNum -= 1);
mongoTemplate.updateFirst(new Query(Criteria.where(VERSION_NUMBER).is(document.getVersionNumber())), Update.update(VERSION_NUMBER, format), ConsulConfigDo.class);
}
versionNumber = 20;
}
//插入到第20个版本
configDo.setVersionNumber(String.format("%02d", versionNumber));
configDo.setHash(hash(configDo.getConsul_content()));
configDo.set_id(System.currentTimeMillis());
mongoTemplate.insert(configDo);
isSync = true;
}
}
return isSync;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 计算hash值
*
* @param key
* @return
*/
private int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
4.consul返回结构类
@Data
public class RestGetResultDo implements Serializable {
private int LockIndex;
private String Key;
private int Flags;
private String Value;
private int CreateIndex;
private int ModifyIndex;
}
5.MongoDB结构
@Validated
@Data
@ToString
@Document(collection = "app_yml_config")
public class ConsulConfigDo {
private Long _id;
private Map consul_content;
private String versionNumber;
private int hash;
}
标签:String,MongoDB,consul,private,化到,版本,configDo,new 来源: https://www.cnblogs.com/han-liu/p/11284587.html