首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

微服務配置中心實戰:Consul + Archaius 實現集中化與動態配置管理

     編輯:Java 綜合教學

問題背景

  • 配置分散在各微服務 application.properties,管理困難。
  • 修改配置需重新編譯、部署、重啟,效率極低。

解決方案架構

  1. 集中管理:Consul KV 存儲所有服務配置(Key: service/{serviceName}/{tag}/config)。
  2. 動態刷新:Archaius (Netflix) 輪詢 Consul,將配置寫入 Spring PropertySource (靜態) 與 Archaius PollResult (動態)。
    — 常改值用 DynamicPropertyFactory 獲取(即時生效)
    — 少改值用 @Value/Environment(需重啟)

核心組件代碼

1. 基礎框架模組依賴

<dependency>
  <groupId>com.netflix.archaius</groupId>
  <artifactId>archaius-core</artifactId>
  <version>0.6.6</version>
</dependency>
<dependency>
  <groupId>commons-configuration</groupId>
  <artifactId>commons-configuration</artifactId>
  <version>1.8</version>
</dependency>

2. Consul 配置數據源

public class ConsulConfigurationSource implements PolledConfigurationSource {
    private String keyName; // service/xxx/yyy/config

    @Override
    public PollResult poll(boolean initial, Object checkPoint) {
        Consul consul = Consul.builder().build();
        String kvStr = consul.keyValueClient().getValueAsString(keyName).or("");
        Properties props = new Properties();
        props.load(new StringReader(kvStr));
        Map<String, Object> map = new HashMap<>();
        for (Object k : props.keySet()) map.put((String)k, props.get(k));
        return PollResult.createFull(map); // 全量刷新
    }
}

預設每 60s 輪詢一次,可調 archaius.fixedDelayPollingScheduler.delayMills。

3. Spring PropertySource 封裝

public class ConsulPropertySource extends MapPropertySource {
    public ConsulPropertySource(String name, Map<String,Object> source) {
        super(name, source);
        // 1. 註冊到 Archaius 動態配置管理器
        PolledConfigurationSource configSource = new ConsulConfigurationSource(name);
        DynamicConfiguration config = new DynamicConfiguration(configSource,
            new FixedDelayPollingScheduler());
        ConfigurationManager.install(config);
        // 2. 同步寫入 Spring PropertySource (靜態快照)
        for (Iterator it = config.getKeys(); it.hasNext(); ) {
            String key = (String) it.next();
            this.source.put(key, config.getProperty(key));
        }
    }
}

4. Bootstrap 初始化器(Spring 啟動早期介入)

public class ConsulPropertySourceBootstrapInitializer
    implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext ctx) {
        ConfigurableEnvironment env = ctx.getEnvironment();
        // 移除默認 application.properties,避免干擾
        env.getPropertySources().remove("applicationConfigurationProperties");
        // 讀取 bootstrap.properties 獲取服務名/標籤
        Properties props = PropertyUtil.loadProps("bootstrap.properties");
        String name = props.getProperty("service.name");
        String tag = props.getProperty("service.tag");
        // 加入 Consul PropertySource
        env.getPropertySources().addLast(new ConsulPropertySource(
            "service/" + name + "/" + tag + "/config", new HashMap<>()));
    }
}

5. 啟動類掛載初始化器

@SpringBootApplication
public class MySpringApplication {
    public void run(String[] args) {
        SpringApplication sa = new SpringApplication(MySpringApplication.class);
        sa.addInitializers(new ConsulPropertySourceBootstrapInitializer());
        sa.addListeners(new ConsulRegisterListener()); // 服務註冊
        sa.run(args);
    }
}

微服務端使用示例

bootstrap.properties:
service.name=myserviceA
service.tag=dev
service.port=8080
@RestController
@RequestMapping("/test/archaius")
public class TestController {
    @Autowired Environment env;
    @Value("${mysql.driverClassName}") String staticVal;

    @GetMapping("/xxx")
    public String test() {
        System.out.println("env -> " + env.getProperty("xxx"));
        System.out.println("@Value -> " + staticVal);
        // 動態獲取(即時感知 Consul 變更)
        DynamicStringProperty dyn = DynamicPropertyFactory.getInstance()
            .getStringProperty("hystrix.command.xxx.timeoutInMilliseconds", "default");
        System.out.println("Dynamic -> " + dyn.get());
        return "hello";
    }
}

難點總結

  • 必須理解 Spring Boot 啟動流程,在 ApplicationContextInitializer 階段注入 PropertySource。
  • 參考 Spring Cloud Config 模式:父 Context 載入配置 → 子 Context 繼承。

這套方案實現了「配置集中存、動態刷新、業務無感」,是微服務治理的關鍵基礎設施。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved