Disconf,百度的分布式配置管理平台

转自:https://blog.csdn.net/wushuchu/article/details/49997625

disconf 可以为各种业务平台提供统一的配置管理服务。

  • 支持配置(配置项+配置文件)的分布式化管理

  • 配置发布统一化

  • 极简的使用方式(注解式编程 或 XML代码无代码侵入模式)

  • 低侵入性或无侵入性、强兼容性

  • 需要Spring编程环境

重要功能特点

  • 支持配置(配置项+配置文件)的分布式化管理

  • 配置发布统一化

    • 配置发布、更新统一化(云端存储、发布):配置存储在云端系统,用户统一在平台上进行发布、更新配置。

    • 配置更新自动化:用户在平台更新配置,使用该配置的系统会自动发现该情况,并应用新配置。特殊地,如果用户为此配置定义了回调函数类,则此函数类会被自动调用。

  • 配置异构系统管理

    • 异构包部署统一化:这里的异构系统是指一个系统部署多个实例时,由于配置不同,从而需要多个部署包(jar或war)的情况(下同)。使用 Disconf后,异构系统的部署只需要一个部署包,不同实例的配置会自动分配。特别地,在业界大量使用部署虚拟化(如JPAAS系统,SAE,BAE) 的情况下,同一个系统使用同一个部署包的情景会越来越多,Disconf可以很自然地与他天然契合。

    • 异构主备自动切换:如果一个异构系统存在主备机,主机发生挂机时,备机可以自动获取主机配置从而变成主机。

    • 异构主备机Context共享工具:异构系统下,主备机切换时可能需要共享Context。可以使用Context共享工具来共享主备的Context。

  • 极简的使用方式(注解式编程 或 XML代码无代码侵入模式):我们追求的是极简的、用户编程体验良好的编程方式。目前支持两种开发模式:基于XML配置或才基于注解,即可完成复杂的配置分布式化。

  • 需要Spring编程环境

注:配置项是指某个类里的某个Field字段。

 
  1. import java.io.File;

  2. import java.io.FileInputStream;

  3. import java.io.IOException;

  4. import java.util.ArrayList;

  5. import java.util.List;

  6. import java.util.Properties;

  7.  
  8. import org.slf4j.Logger;

  9. import org.slf4j.LoggerFactory;

  10.  
  11. import com.baidu.disconf.client.config.ConfigMgr;

  12. import com.baidu.disconf.client.config.DisClientConfig;

  13. import com.baidu.disconf.client.config.DisClientSysConfig;

  14. import com.baidu.disconf.client.fetcher.FetcherFactory;

  15. import com.baidu.disconf.client.fetcher.FetcherMgr;

  16. import com.baidu.disconf.core.common.constants.DisConfigTypeEnum;

  17. import com.baidu.disconf.core.common.path.DisconfWebPathMgr;

  18.  
  19.  
  20. /**

  21. * 下载所有的disconf文件 *

  22.  
  23. *

  24. */

  25. public class DisConfUtils {

  26.  
  27. public static final Logger logger = LoggerFactory.getLogger(DisConfUtils.class);

  28.  
  29. /**

  30. * 加载配置文件

  31. *

  32. * @return

  33. * @throws IOException

  34. */

  35. private static Properties loadProperties() throws IOException {

  36.  
  37. // 将我们的配置装载到properties中

  38. Properties pro = new Properties();

  39. // 获得disconf配置文件的路径

  40. String proPath = StringUtils.spliceUrl(ObjectUtils.getClassPath(), "disconf.properties");

  41. FileInputStream fin = null;

  42. try {

  43. fin = new FileInputStream(proPath);

  44. pro.load(fin);

  45. } finally {

  46. if (!ObjectUtils.isNull(fin)) {

  47. try {

  48. fin.close();

  49. } catch (IOException e) {

  50. logger.error("close disconf.properties file Inputstream err", e);

  51. }

  52. }

  53. }

  54. return pro;

  55. }

  56.  
  57. /**

  58. * 加载本地的配置文件

  59. *

  60. * @return

  61. */

  62. private static String[] loadLocal() {

  63. String basePath = ObjectUtils.getClassPath();

  64. File baseFile = new File(basePath);

  65. String[] xmlPaths = null;

  66.  
  67. String fileName = "";

  68. List<String> xmlList = new ArrayList<>();

  69.  
  70. for (File sunFile : baseFile.listFiles()) {

  71. fileName = sunFile.getName();

  72. if (fileName.endsWith(".xml")) {

  73. xmlList.add("classpath:" + fileName);

  74. }

  75. }

  76. xmlPaths = new String[xmlList.size()];

  77. xmlList.toArray(xmlPaths);

  78. return xmlPaths;

  79. }

  80.  
  81. /**

  82. * 加载远程的配置文件

  83. *

  84. * @return

  85. * @throws Exception

  86. */

  87. private static String[] loadRemove() throws Exception {

  88. String[] xmlPaths = null;

  89. Properties disProperties = null;

  90. try {

  91. // 加载默认的配置文件

  92. disProperties = loadProperties();

  93. } catch (Exception e) {

  94. logger.error("load disconf properties file InputStream err", e);

  95. throw new Exception("load disconf properties file InputStream err", e);

  96. }

  97.  
  98. try {

  99. // 初始化disconf的客户端

  100. ConfigMgr.init();

  101. // 获得disconf客户端的系统配置

  102. DisClientSysConfig sysConfig = DisClientSysConfig.getInstance();

  103. // 获得disconf客户端的配置

  104. DisClientConfig config = DisClientConfig.getInstance();

  105. // 获得下载disconf文件的对象

  106. FetcherMgr fetcherMgr = FetcherFactory.getFetcherMgr();

  107.  
  108. // 获得下载文件的文件路径

  109. String downloadFiles = disProperties.getProperty("conf_server_download");

  110. if (!StringUtils.isEmpty(downloadFiles)) {

  111. List<String> xmlList = new ArrayList<>();

  112. String[] fileNames = downloadFiles.split(",");

  113. String url = "";

  114. // 循环下载配置文件

  115. for (String fileName : fileNames) {

  116. url = DisconfWebPathMgr.getRemoteUrlParameter(sysConfig.CONF_SERVER_STORE_ACTION, config.APP,

  117. config.VERSION, config.ENV, fileName, DisConfigTypeEnum.FILE);

  118. fetcherMgr.downloadFileFromServer(url, fileName);

  119. if (fileName.endsWith(".xml")) {

  120. // 如果是xml后缀则需要添加上相对路径

  121. xmlList.add("classpath:" + fileName);

  122. }

  123. }

  124. xmlPaths = new String[xmlList.size()];

  125. xmlList.toArray(xmlPaths);

  126. }

  127.  
  128. } catch (Exception e) {

  129. logger.error("connect disconf service err", e);

  130. }

  131.  
  132. return xmlPaths;

  133. }

  134.  
  135. /**

  136. * 连接disconf的服务器端,并下载服务器中的数据

  137. *

  138. * @return

  139. * @throws Exception

  140. */

  141. public static String[] loadDisconf() throws Exception {

  142. // 首选加载远程的配置

  143. String[] locations = loadRemove();

  144. if (ObjectUtils.isNull(locations) || locations.length <= 0) {

  145. // 如果无法加载到远程的配置文件,则加载本地的配置文件

  146. locations = loadLocal();

  147. }

  148. return locations;

  149. }

  150.  
  151. }


 

 
  1. import javax.servlet.ServletContext;

  2.  
  3. import org.slf4j.Logger;

  4. import org.slf4j.LoggerFactory;

  5. import org.springframework.web.context.ConfigurableWebApplicationContext;

  6. import org.springframework.web.context.ContextLoaderListener;

  7. import org.springframework.web.context.WebApplicationContext;

  8.  
  9.  
  10. /**

  11. * 重写spring的配置文件加载的监听器 实现disconf服务器上的文件下载并将下载后的spring配置文件装入spring的路径中

  12. *

  13. *

  14. */

  15. public class ContextListener extends ContextLoaderListener {

  16.  
  17. public static final Logger logger = LoggerFactory.getLogger(ContextListener.class);

  18.  
  19. public ContextListener() {

  20. }

  21.  
  22. public ContextListener(WebApplicationContext context) {

  23. super(context);

  24. }

  25.  
  26. /**

  27. * 重写父接口的创建ApplicationContext的类

  28. */

  29. protected WebApplicationContext createWebApplicationContext(ServletContext sc) {

  30.  
  31. // 调用父类的方法

  32. WebApplicationContext cont = super.createWebApplicationContext(sc);

  33. if (null != cont) {

  34. // 如果获取成功,强制类型转换

  35. ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) cont;

  36. try {

  37. // 下载并获得所有的spring的配置文件的路径

  38. String[] locations = DisConfUtils.loadDisconf();

  39. // 设置spring的文件路径到Application的路径中

  40. wac.setConfigLocations(locations);

  41. } catch (Exception e) {

  42. logger.error("load spring config xml file error",e);

  43. throw new IllegalStateException("DownLoad spring xml error");

  44. }

  45. }

  46. return cont;

  47. }

  48.  
  49. }

猜你喜欢

转载自blog.csdn.net/qq_36688928/article/details/81479276