春云配置服务器提供了微服务获取配置的功能,这些配置文件(application.yml或者application.properties)通常维护在git或者数据库中,而且支持通过RefreshScope动态刷新,使用起来还是比较灵活的。但是当微服务越来越多时,会遇到下面几个问题:
-
<李>配置文件的敏感数如数据库地址和账号信息,据呈现在每个配置文件中,替换起来需要一个个配置文件进行修改。李>
<李>各个微服务配置文件存在很多冗余配置(如尤里卡,假装),一旦这些部分调整,需要针对每个微服务进行调整,运维压力大增。李>
为了解决上述问题,我们可以从configServer服务着手进行改造,示意如下:
不同的服务ABC,不管是在配置中心仓库端配置了多少个文件,从ConfigServer返回的,一定是服务最终应用的配置。获取配置的方式,通常是调用ConfigServer的一个地址,如:
http://localhost: 8021/common_rent/dev/aliyun_dev
common_rent是应用程序名称,dev是侧面,aliyun_dev是标签(git的分支)。这个地址的处理接口,是ConfigServer的EnvironmentController,所以通过拦截这个接口,将敏感信息或者公共配置抽取到ConfigServer的应用程序。yml、返回前进行替换或者拼接,即可实现上述目的。
代码示例:
-
<李>
拦截器实现
<代码> @ component @Aspect 公开课ResourceLoaderInterceptor { 私有静态日志记录器=LogFactory.getLog (ResourceLoaderInterceptor.class); @ ExternalProperties ExternalProperties; @Around(“执行(* org.springframework.cloud.config.server . . *控制器。* (. .)") 公共对象commonPropertiesResolve (ProceedingJoinPoint连接点)抛出Throwable { 对象returnObj=零; 对象[]参数=joinPoint.getArgs (); 秒表秒表=new秒表(); 尝试{ stopWatch.start (); returnObj=joinPoint.proceed (args); 如果(Environment.class.isInstance (returnObj)) { 环境环境=(环境)returnObj; 如果(environment.getPropertySources() !=零,,.size environment.getPropertySources()()在0) { (PropertySource PropertySource: environment.getPropertySources ()) { placeHolderResolve ((Map<字符串,Object>) propertySource.getSource ()); } } } }捕捉(Throwable Throwable) { logger.error (ExceptionUtils.getStackTrace (throwable)); 最后}{ stopWatch.stop (); System.out.println (stopWatch.getTotalTimeMillis ()); } 返回returnObj; } 私人空间placeHolderResolve (Map<字符串,Object>源){ Object> Map<字符串;占位符=collectConfigSet (); (字符串关键:source.keySet ()) { 对象价值=https://www.yisu.com/zixun/source.get(关键); 对象valueAfterReplace=零; 如果(价值!=null) { 如果(String.class.isInstance(值)& & ((String)值).contains (“$ {ext。”)) { 字符串varExp=(字符串)值; (字符串变量:placeHolders.keySet ()) { 字符串vk=" ${+变量+“}”; 如果(varExp.contains (vk)) { 对象replaceValue=https://www.yisu.com/zixun/placeHolders.get(变量); 如果(replaceValue !=null) { 如果(varExp.equalsIgnoreCase (vk)) { valueAfterReplace=replaceValue; 打破; 其他}{ varExp=stringutil的。替换(varExp vk”、“+ replaceValue); 如果(! varExp.contains (“$ {”)) { 打破; } } 其他}{ 记录器。错误(“财产”+ vk +“不是正确配置!”); } } } 如果(valueAfterReplace !=null) { 源。把(关键,valueAfterReplace); }else if (varExp.contains (“$ {”)) { 记录器。错误(“财产”+ varExp +“不是正确配置!”); 其他}{ 源。把(关键,varExp); } } } } } 私人Map<字符串,Object>collectConfigSet () { Object> Map<字符串;占位符=new HashMap<在(); ?[]字段ExternalProperties.class.getDeclaredFields (); for (int i=0;我& lt;fields.length;我+ +){ 尝试{ 场propertiesField=[我]字段; ResourcePrefix ResourcePrefix=propertiesField.getAnnotation (ResourcePrefix.class); 字符串前缀=resourcePrefix.value (); ExtDataSource ExtDataSource=(ExtDataSource) BeanUtils.getPropertyDescriptor (ExternalProperties。类,propertiesField.getName ()) .getReadMethod () .invoke (externalProperties); 如果(extDataSource !=null) { 场[]fields2=ExtDataSource.class.getDeclaredFields (); (字段datasourceField: fields2) { 尝试{ ResourcePrefix注释=datasourceField.getAnnotation (ResourcePrefix.class); 字符串的后缀=annotation.value (); 对象sourceFieldValue=https://www.yisu.com/zixun/BeanUtils.getPropertyDescriptor (ExtDataSource.class datasourceField.getName ()) .getReadMethod () .invoke (extDataSource); 如果(sourceFieldValue !=null) { 占位符。把(前缀+”。”+后缀,sourceFieldValue); } }捕捉(异常e) { logger.error (ExceptionUtils.getStackTrace (e)); } } } }捕捉(异常e) { logger.error (ExceptionUtils.getStackTrace (e)); } } 返回占位符; } }春云微服务公共配置处理