← 返回首页
🌐

分布式配置:CAP一致性与配置推送

📂 architecture ⏱ 2 min 248 words

分布式配置:CAP一致性与配置推送

CAP理论与配置系统

配置中心需要在CAP之间做出权衡。大多数配置系统选择AP(可用性优先),保证配置读取的高可用,同时通过最终一致性保证配置的正确传播。

// 配置中心核心接口
public interface ConfigCenter {
    // 获取配置
    String getConfig(String key, String defaultValue);
    
    // 获取配置(带超时)
    String getConfig(String key, String defaultValue, long timeoutMs);
    
    // 监听配置变化
    void addListener(String key, ConfigChangeListener listener);
    
    // 发布配置
    void publishConfig(String key, String value);
    
    // 获取配置版本号
    long getConfigVersion(String key);
}

配置推送机制

配置推送有三种方式:轮询(Pull)、长轮询(Long Polling)和推送(Push)。长轮询是性能和实时性的平衡选择。

# 长轮询实现
class LongPollingClient:
    def __init__(self, config_center_url: str):
        self.url = config_center_url
        self.session = requests.Session()
    
    def poll(self, keys: list, timeout: int = 60) -> dict:
        """长轮询获取配置变更"""
        response = self.session.get(
            f"{self.url}/configs/poll",
            params={'keys': ','.join(keys), 'timeout': timeout},
            timeout=timeout + 10
        )
        return response.json()
    
    def watch(self, keys: list, callback: Callable):
        """持续监听配置变更"""
        while True:
            try:
                changes = self.poll(keys)
                if changes:
                    callback(changes)
            except requests.exceptions.Timeout:
                continue
            except Exception as e:
                time.sleep(5)  # 退避重试

Apollo配置中心架构

Apollo采用Config Service + Admin Service的架构,支持灰度发布和配置版本管理。

// Apollo客户端使用
@ApolloConfig
public class AppConfig {
    @Value("${database.url:jdbc:mysql://localhost:3306/mydb}")
    private String databaseUrl;
    
    @Value("${cache.ttl:300}")
    private int cacheTtl;
    
    @ApolloConfigChangeListener("application")
    public void onConfigChange(ConfigChangeEvent event) {
        if (event.isChanged("database.url")) {
            String newUrl = event.getChange("database.url").getNewValue();
            refreshDataSource(newUrl);
        }
        if (event.isChanged("cache.ttl")) {
            int newTtl = Integer.parseInt(event.getChange("cache.ttl").getNewValue());
            refreshCacheConfig(newTtl);
        }
    }
}

// Apollo灰度发布配置
// 1. 在Admin Service标记灰度实例
// 2. 灰度配置只推送给灰度实例
// 3. 验证通过后全量发布

Nacos配置管理

Nacos同时支持CP和AP模式,提供配置管理和服务发现的统一平台。

// Nacos配置监听
@Component
public class NacosConfigListener {
    @PostConstruct
    public void init() throws NacosException {
        String serverAddr = "localhost:8848";
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        
        ConfigService configService = NacosFactory.createConfigService(properties);
        
        // 获取配置
        String config = configService.getConfig("my-config.yaml", "DEFAULT_GROUP", 5000);
        
        // 监听配置变化
        configService.addListener("my-config.yaml", "DEFAULT_GROUP", new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }
            
            @Override
            public void receiveConfigInfo(String configInfo) {
                log.info("Config changed: {}", configInfo);
                refreshConfig(configInfo);
            }
        });
    }
}

// Nacos配置发布
configService.publishConfig("my-config.yaml", "DEFAULT_GROUP", newConfig);

配置管理最佳实践

配置变更需要灰度发布机制,先在少量实例验证,再全量推送。敏感配置(密码、密钥)需要加密存储,运行时解密。配置版本管理支持快速回滚,应对配置错误。配置中心本身需要高可用部署,避免成为单点故障。