分布式配置:CAP一致性与配置推送
分布式配置: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);
配置管理最佳实践
配置变更需要灰度发布机制,先在少量实例验证,再全量推送。敏感配置(密码、密钥)需要加密存储,运行时解密。配置版本管理支持快速回滚,应对配置错误。配置中心本身需要高可用部署,避免成为单点故障。