disconf-web是基于tomcat,springMVC构建的web应用,tomcat启动时,会加载webapp下面的web.xml
可以看出spring profile默认为production,对应的applicationContext.xml文件bean加载为:
可以看出里面需要加载真实的mysql,redis和zookeeper配置。
此外,web.xml里面加载了两个自定义的
StartupListener
和ContextListener
,分别是用来设置本地Local环境
和加载spring的applicationContext
的。
首先看一下mysql的数据表信息:
对外暴露的Controller如下:
image.png
UserController
从db校验通过登陆成功后,会把用户信息存放到session和redis中
/**
* 登录
*/
@Override
public void login(HttpServletRequest request, User user, int expireTime) {
Visitor visitor = new Visitor();
//
//
//
visitor.setId(user.getId());
visitor.setLoginUserId(user.getId());
visitor.setLoginUserName(user.getName());
visitor.setRoleId(user.getRoleId());
visitor.setAppIds(user.getOwnApps());
//
// 更新session
//
updateSessionVisitor(request.getSession(), visitor);
//
// 更新Redis数据
//
updateRedisVisitor(visitor, request, expireTime);
}
在之后的校验中通过LoginInterceptor进行登陆认证校验,通过注解@NoAuth进行权限校验
image.png
image.png
ConfigNewController
/**
* 配置文件的新建(使用上传配置文件)
*/
@ResponseBody
@RequestMapping(value = "/file", method = RequestMethod.POST)
public JsonObjectBase updateFile(@Valid ConfNewForm confNewForm, @RequestParam("myfilerar") MultipartFile file) {
LOG.info(confNewForm.toString());
//
// 校验
//
int fileSize = 1024 * 1024 * 4;
String[] allowExtName = {".properties", ".xml"};
fileUploadValidator.validateFile(file, fileSize, allowExtName);
//
// 更新
//
String fileContent = "";
try {
fileContent = new String(file.getBytes(), "UTF-8");
LOG.info("receive file: " + fileContent);
} catch (Exception e) {
LOG.error(e.toString());
throw new FileUploadException("upload file error", e);
}
// 创建配置文件表格
ConfNewItemForm confNewItemForm = new ConfNewItemForm(confNewForm);
confNewItemForm.setKey(file.getOriginalFilename());
confNewItemForm.setValue(fileContent);
// 业务校验
configValidator.validateNew(confNewItemForm, DisConfigTypeEnum.FILE);
//
configMgr.newConfig(confNewItemForm, DisConfigTypeEnum.FILE);
return buildSuccess("创建成功");
}
只会在数据库中创建config和config_history数据,如果开启邮件通知的话,会通知application.properties中设置的邮箱地址
ConfigUpdateController
/**
* 配置文件的更新
*/
@ResponseBody
@RequestMapping(value = "/file/{configId}", method = RequestMethod.POST)
public JsonObjectBase updateFile(@PathVariable long configId, @RequestParam("myfilerar") MultipartFile file) {
//
// 校验
//
int fileSize = 1024 * 1024 * 4;
String[] allowExtName = {".properties", ".xml"};
fileUploadValidator.validateFile(file, fileSize, allowExtName);
// 业务校验
configValidator.validateUpdateFile(configId, file.getOriginalFilename());
//
// 更新
//
String emailNotification = "";
try {
String str = new String(file.getBytes(), "UTF-8");
LOG.info("receive file: " + str);
emailNotification = configMgr.updateItemValue(configId, str);
LOG.info("update " + configId + " ok");
} catch (Exception e) {
LOG.error(e.toString());
throw new FileUploadException("upload file error", e);
}
//
// 通知ZK
//
configMgr.notifyZookeeper(configId);
return buildSuccess(emailNotification);
}
更新数据库,如果zk相关配置文件节点存在,会更新zk node
关于定时校验中心的配置与所有客户端配置的一致性
使用spring定时任务@Scheduled实现:
关于为什么使用mysql作为配置获取,而不是zk
网友评论