Apollo与SpringCloud集成
2026/1/15大约 4 分钟ApolloApolloSpringCloud分布式配置中心配置管理灰度发布动态配置
1. Spring Cloud 集成概述
1.1 集成方式
Apollo 与 Spring Cloud 的集成主要有两种方式:
| 方式 | 说明 | 适用场景 |
|---|---|---|
| apollo-client | 原生客户端 | 通用场景 |
| apollo-client-config-data | Spring Boot 2.4+ Config Data | 新项目推荐 |
1.2 版本兼容性
| Apollo Client | Spring Boot | Spring Cloud |
|---|---|---|
| 2.1.x | 2.4.x - 3.x | 2020.x - 2022.x |
| 2.0.x | 2.0.x - 2.3.x | Finchley - Hoxton |
| 1.9.x | 1.5.x - 2.3.x | Edgware - Hoxton |
2. 基础集成
2.1 添加依赖
<dependencies>
<!-- Spring Cloud 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- Apollo 客户端 -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>2.2 Bootstrap 配置
在 bootstrap.yml 中配置 Apollo:
app:
id: ${spring.application.name}
apollo:
meta: http://localhost:8080
bootstrap:
enabled: true
namespaces: application
eagerLoad:
enabled: true3. 动态刷新 Bean
3.1 刷新 @ConfigurationProperties Bean
当配置变更时,自动刷新 @ConfigurationProperties 标注的 Bean:
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.springframework.beans.BeansException;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApolloRefreshConfig implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 监听配置变更,刷新 Spring Environment
*/
@ApolloConfigChangeListener
public void onChange(ConfigChangeEvent changeEvent) {
// 发布环境变更事件,触发 @ConfigurationProperties 刷新
applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
}
}3.2 刷新数据源配置
当数据源配置变更时,动态刷新数据源:
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
@Component
public class DataSourceRefreshConfig {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private DataSourceProperties dataSourceProperties;
@Autowired
private DataSource dataSource;
@ApolloConfigChangeListener(interestedKeyPrefixes = "spring.datasource")
public void onDataSourceChange(ConfigChangeEvent changeEvent) {
// 发布环境变更事件
applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
// 刷新数据源(如果使用 HikariCP)
if (dataSource instanceof com.zaxxer.hikari.HikariDataSource) {
com.zaxxer.hikari.HikariDataSource hikariDataSource =
(com.zaxxer.hikari.HikariDataSource) dataSource;
hikariDataSource.setJdbcUrl(dataSourceProperties.getUrl());
hikariDataSource.setUsername(dataSourceProperties.getUsername());
hikariDataSource.setPassword(dataSourceProperties.getPassword());
System.out.println("数据源配置已刷新");
}
}
}4. 与 Spring Cloud Gateway 集成
4.1 动态路由配置
在 Apollo 中配置路由:
# Namespace: gateway-routes.yml
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=14.2 动态刷新路由
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class GatewayRouteRefreshConfig {
@Autowired
private ApplicationEventPublisher publisher;
@ApolloConfigChangeListener(value = "gateway-routes.yml",
interestedKeyPrefixes = "spring.cloud.gateway")
public void onRouteChange(ConfigChangeEvent changeEvent) {
// 发布路由刷新事件
publisher.publishEvent(new RefreshRoutesEvent(this));
System.out.println("Gateway 路由配置已刷新");
}
}5. 与 Nacos 服务发现配合使用
5.1 架构说明
5.2 配置示例
# bootstrap.yml
spring:
application:
name: demo-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: dev
# Apollo 配置
app:
id: demo-service
apollo:
meta: http://localhost:8080
bootstrap:
enabled: true
namespaces: application6. 与 Sentinel 集成
6.1 动态规则配置
在 Apollo 中配置 Sentinel 规则:
// Namespace: sentinel-rules
// Key: flow-rules
[
{
"resource": "/api/user/info",
"limitApp": "default",
"grade": 1,
"count": 100,
"strategy": 0,
"controlBehavior": 0
}
]6.2 规则动态刷新
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class SentinelApolloConfig {
@Bean
public void initSentinelRules() {
// 流控规则
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource =
new ApolloDataSource<>(
"sentinel-rules", // namespace
"flow-rules", // key
"", // 默认值
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})
);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}7. 配置加密
7.1 使用 Jasypt 加密
添加依赖:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>7.2 加密配置值
# 使用 Jasypt 加密
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \
input="your_password" \
password="encryption_key" \
algorithm=PBEWithMD5AndDES7.3 在 Apollo 中使用加密值
# Apollo 配置
spring.datasource.password=ENC(加密后的密文)7.4 配置解密密钥
# application.yml
jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD} # 从环境变量获取
algorithm: PBEWithMD5AndDES8. 日志级别动态调整
8.1 配置日志级别
在 Apollo 中配置:
# 日志级别配置
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.level.org.springframework=WARN8.2 动态刷新日志级别
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.stereotype.Component;
@Component
public class LoggingLevelRefreshConfig {
private static final Logger logger = LoggerFactory.getLogger(LoggingLevelRefreshConfig.class);
private static final String LOGGING_LEVEL_PREFIX = "logging.level.";
@Autowired
private LoggingSystem loggingSystem;
@ApolloConfigChangeListener(interestedKeyPrefixes = LOGGING_LEVEL_PREFIX)
public void onLoggingLevelChange(ConfigChangeEvent changeEvent) {
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
String loggerName = key.substring(LOGGING_LEVEL_PREFIX.length());
String newLevel = change.getNewValue();
LogLevel level = LogLevel.valueOf(newLevel.toUpperCase());
loggingSystem.setLogLevel(loggerName, level);
logger.info("日志级别变更: {} -> {}", loggerName, newLevel);
}
}
}9. 完整微服务示例
9.1 项目结构
9.2 Apollo Namespace 规划
9.3 配置加载顺序
10. 总结
本节我们学习了 Apollo 与 Spring Cloud 的深度集成:
- 动态刷新 Bean:配置变更时自动刷新 Spring Bean
- Gateway 动态路由:实现路由配置的热更新
- Sentinel 规则管理:动态管理限流降级规则
- 配置加密:保护敏感配置信息
- 日志级别动态调整:运行时调整日志级别
下一节我们将学习 Apollo 的高级特性和原理。
