Java配置中心详解
Java配置中心详解
为什么需要配置中心
- 配置集中管理,避免配置散落在各服务
- 动态更新配置,无需重启应用
- 多环境配置隔离
- 配置版本管理和灰度发布
Nacos配置中心
基本使用
# bootstrap.yml
spring:
application:
name: user-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
group: DEFAULT_GROUP
namespace: dev
配置数据模型
Namespace → Group → Data ID
例如:
namespace=dev, group=DEFAULT_GROUP, dataId=user-service.yaml
动态配置刷新
@RefreshScope
@Service
public class FeatureService {
@Value("${app.features.dark-mode:false}")
private boolean darkMode;
@Value("${app.features.new-checkout:false}")
private boolean newCheckout;
@Value("${app.config.max-retry:3}")
private int maxRetry;
public boolean isDarkMode() {
return darkMode;
}
}
// 配置变更后自动刷新,无需重启
配置监听
@Component
public class ConfigListener {
@PostConstruct
public void init() throws NacosException {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "localhost:8848");
ConfigService configService = NacosFactory.createConfigService(properties);
String dataId = "user-service.yaml";
String group = "DEFAULT_GROUP";
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("配置变更: " + configInfo);
// 处理配置变更
}
});
}
}
Apollo配置中心
依赖配置
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>2.2.0</version>
</dependency>
配置
apollo:
bootstrap:
enabled: true
eagerLoadEnabled: true
meta: http://localhost:8080
app:
id: user-service
使用Apollo配置
@SpringBootApplication
public class ApolloApplication {
public static void main(String[] args) {
ApolloConfigManager.getInstance().init();
SpringApplication.run(ApolloApplication.class, args);
}
}
@ApolloConfig
public class ApolloConfigDemo {
// @Value方式
@Value("${app.timeout:30}")
private int timeout;
// @ApolloConfigValue方式
@ApolloConfigValue("${app.retry:3}")
private int retry;
// 监听配置变更
@ApolloConfigChangeListener
public void onChange(ConfigChangeEvent changeEvent) {
changeEvent.changedKeys().forEach(key -> {
ConfigChange change = changeEvent.getChange(key);
System.out.printf("配置变更: %s, 旧值: %s, 新值: %s%n",
key, change.getOldValue(), change.getNewValue());
});
}
}
多环境配置
# application.yml
spring:
profiles:
active: ${PROFILE:dev}
---
# 开发环境
spring:
config:
activate:
on-profile: dev
app:
db-url: jdbc:mysql://dev-db:3306/mydb
redis-host: dev-redis
---
# 生产环境
spring:
config:
activate:
on-profile: prod
app:
db-url: jdbc:mysql://prod-db:3306/mydb
redis-host: prod-redis
配置加密
@Component
public class EncryptedConfig {
private final TextEncryptor encryptor;
public EncryptedConfig(TextEncryptor encryptor) {
this.encryptor = encryptor;
}
public String decrypt(String encryptedValue) {
return encryptor.decrypt(encryptedValue);
}
// 使用
@Value("${app.db.password:ENC(encrypted_password)}")
private String encryptedPassword;
public String getPassword() {
return decrypt(encryptedPassword);
}
}
配置灰度发布
@Service
public class GrayReleaseService {
@Value("${app.gray.enabled:false}")
private boolean grayEnabled;
@Value("${app.gray.percentage:0}")
private int grayPercentage;
public boolean shouldUseGray(String userId) {
if (!grayEnabled) return false;
int hash = Math.abs(userId.hashCode()) % 100;
return hash < grayPercentage;
}
}
最佳实践
// 1. 配置项使用有意义的命名
app.feature.user-registration=true
app.config.max-connections=100
// 2. 设置合理的默认值
@Value("${app.timeout:30}")
private int timeout;
// 3. 敏感配置加密存储
app.db.password=ENC(xxxxx)
// 4. 配置分组管理
# 数据库配置
app.db.url=...
app.db.username=...
app.db.password=...
# 缓存配置
app.redis.host=...
app.redis.port=...
总结
配置中心是微服务架构的基础设施。Nacos同时提供配置中心和服务发现,Apollo专注于配置管理且功能更丰富。选择时根据团队技术栈和功能需求决定。