5.1 配置中心概述
什么是配置中心
配置中心是微服务架构中用于集中管理应用程序配置的组件。它提供了统一的配置存储、版本控制、动态更新和环境隔离等功能,解决了传统配置管理的痛点。
配置中心的作用
┌─────────────────────────────────────────────────────────────────┐
│ 配置中心架构图 │
├─────────────────────────────────────────────────────────────────┤
│ 开发人员 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 开发环境 │ │ 测试环境 │ │ 生产环境 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 配置中心 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │
│ │ │ 配置存储 │ │ 版本控制 │ │ 权限管理 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │
│ │ │ 动态刷新 │ │ 环境隔离 │ │ 配置审计 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ │
│ └─────────────────────┬───────────────────────────────────┘ │
├────────────────────────┼───────────────────────────────────────┤
│ │ 配置拉取/推送 │
│ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ User Service │ │ Product Service │ │ Order Service │ │
│ │ Config Client │ │ Config Client │ │ Config Client │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
核心功能
- 集中管理:统一存储和管理所有服务的配置信息
- 环境隔离:支持开发、测试、生产等多环境配置
- 动态刷新:支持配置的热更新,无需重启服务
- 版本控制:配置变更的版本管理和回滚
- 权限控制:细粒度的配置访问权限管理
- 配置审计:配置变更的审计日志
- 高可用:配置中心的集群部署和故障转移
- 安全加密:敏感配置的加密存储
传统配置管理的问题
- 配置分散:配置文件散布在各个服务中,难以统一管理
- 环境混乱:不同环境的配置容易混淆
- 更新困难:配置变更需要重新部署服务
- 版本管理:缺乏配置的版本控制和回滚机制
- 安全风险:敏感配置明文存储,存在安全隐患
5.2 Spring Cloud Config
Config简介
Spring Cloud Config是Spring Cloud生态系统中的配置管理解决方案,提供了服务端和客户端的支持,可以集中管理各个环境的配置文件。
核心组件
- Config Server:配置服务端,提供配置的存储和访问
- Config Client:配置客户端,从Config Server获取配置
- 配置仓库:存储配置文件的仓库(Git、SVN、本地文件系统等)
5.3 Config Server搭建
1. 创建Config Server项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>config-server</artifactId>
<version>1.0.0</version>
<name>config-server</name>
<description>Configuration Server</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
</properties>
<dependencies>
<!-- Config Server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- Eureka Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2. 启动类
ConfigServerApplication.java
package com.example.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* 配置中心服务端启动类
*/
@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
3. 配置文件
application.yml
server:
port: 8888
spring:
application:
name: config-server
# 配置仓库
cloud:
config:
server:
git:
# Git仓库地址
uri: https://github.com/your-username/config-repo.git
# 搜索路径
search-paths: '{application}'
# 默认分支
default-label: main
# 用户名和密码(私有仓库)
username: your-username
password: your-password
# 克隆超时时间
timeout: 10
# 强制拉取
force-pull: true
# 删除未跟踪的分支
delete-untracked: true
# 本地仓库路径
basedir: /tmp/config-repo
# 本地文件系统配置(开发环境)
native:
search-locations: classpath:/config/,file:./config/
# 健康检查
health:
repositories:
user-service:
label: main
name: user-service
profiles: dev
# 加密配置
encrypt:
enabled: true
# 安全配置
security:
user:
name: config-admin
password: config-password
roles: ADMIN
# Eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
lease-renewal-interval-in-seconds: 10
lease-expiration-duration-in-seconds: 30
# 监控配置
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
configprops:
show-values: always
# 日志配置
logging:
level:
org.springframework.cloud.config: DEBUG
org.springframework.web: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
4. 安全配置
SecurityConfig.java
package com.example.configserver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
/**
* 安全配置
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(authz -> authz
.requestMatchers("/actuator/health", "/actuator/info").permitAll()
.anyRequest().authenticated()
)
.httpBasic();
return http.build();
}
}
5.4 配置仓库结构
Git仓库结构
config-repo/
├── application.yml # 全局默认配置
├── application-dev.yml # 全局开发环境配置
├── application-test.yml # 全局测试环境配置
├── application-prod.yml # 全局生产环境配置
├── user-service/
│ ├── user-service.yml # 用户服务默认配置
│ ├── user-service-dev.yml # 用户服务开发环境配置
│ ├── user-service-test.yml # 用户服务测试环境配置
│ └── user-service-prod.yml # 用户服务生产环境配置
├── product-service/
│ ├── product-service.yml
│ ├── product-service-dev.yml
│ ├── product-service-test.yml
│ └── product-service-prod.yml
└── order-service/
├── order-service.yml
├── order-service-dev.yml
├── order-service-test.yml
└── order-service-prod.yml
配置文件示例
全局配置 - application.yml
# 全局默认配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 300000
connection-timeout: 20000
max-lifetime: 1200000
jpa:
hibernate:
ddl-auto: validate
show-sql: false
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
format_sql: true
redis:
timeout: 2000ms
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1ms
# 日志配置
logging:
level:
com.example: INFO
org.springframework.web: WARN
org.hibernate.SQL: WARN
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
# 监控配置
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when-authorized
开发环境配置 - application-dev.yml
# 开发环境全局配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/microservice_dev?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: dev_user
password: '{cipher}AQA...encrypted_password...'
redis:
host: localhost
port: 6379
database: 0
jpa:
hibernate:
ddl-auto: update
show-sql: true
# 日志配置
logging:
level:
com.example: DEBUG
org.springframework.web: DEBUG
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
file:
name: logs/application-dev.log
# 监控配置
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
用户服务配置 - user-service.yml
# 用户服务默认配置
server:
port: 8081
spring:
application:
name: user-service
datasource:
hikari:
maximum-pool-size: 10
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# 业务配置
user:
service:
# 密码加密盐值
password-salt: '{cipher}AQB...encrypted_salt...'
# JWT配置
jwt:
secret: '{cipher}AQC...encrypted_jwt_secret...'
expiration: 86400
# 验证码配置
captcha:
enabled: true
length: 4
expire-time: 300
# 邮件配置
email:
enabled: true
smtp:
host: smtp.example.com
port: 587
username: noreply@example.com
password: '{cipher}AQD...encrypted_email_password...'
# Eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
用户服务开发环境配置 - user-service-dev.yml
# 用户服务开发环境配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/user_service_dev?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: user_dev
password: '{cipher}AQE...encrypted_dev_password...'
redis:
database: 1
# 业务配置
user:
service:
# 开发环境允许跳过验证码
captcha:
enabled: false
# 开发环境邮件配置
email:
enabled: false
# 使用控制台输出代替真实邮件发送
mock: true
# 日志配置
logging:
level:
com.example.userservice: DEBUG
5.5 Config Client配置
1. 添加依赖
pom.xml
<!-- Config Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- Bootstrap -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- Actuator for refresh -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2. Bootstrap配置
bootstrap.yml
spring:
application:
name: user-service
profiles:
active: dev
cloud:
config:
# Config Server地址
uri: http://localhost:8888
# 配置文件名(默认为应用名)
name: ${spring.application.name}
# 环境(对应profiles)
profile: ${spring.profiles.active}
# 分支
label: main
# 认证信息
username: config-admin
password: config-password
# 快速失败
fail-fast: true
# 重试配置
retry:
initial-interval: 1000
max-attempts: 6
max-interval: 2000
multiplier: 1.1
# 请求超时
request-connect-timeout: 5000
request-read-timeout: 10000
# Eureka配置(用于服务发现Config Server)
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
3. 动态刷新配置
配置类
UserServiceConfig.java
package com.example.userservice.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* 用户服务配置
*/
@Component
@ConfigurationProperties(prefix = "user.service")
@RefreshScope
@Data
public class UserServiceConfig {
private String passwordSalt;
private JwtConfig jwt = new JwtConfig();
private CaptchaConfig captcha = new CaptchaConfig();
private EmailConfig email = new EmailConfig();
@Data
public static class JwtConfig {
private String secret;
private Long expiration;
}
@Data
public static class CaptchaConfig {
private Boolean enabled;
private Integer length;
private Integer expireTime;
}
@Data
public static class EmailConfig {
private Boolean enabled;
private Boolean mock;
private SmtpConfig smtp = new SmtpConfig();
@Data
public static class SmtpConfig {
private String host;
private Integer port;
private String username;
private String password;
}
}
}
配置刷新端点
application.yml
# 监控配置
management:
endpoints:
web:
exposure:
include: refresh,health,info
endpoint:
refresh:
enabled: true
配置刷新控制器
ConfigController.java
package com.example.userservice.controller;
import com.example.userservice.config.UserServiceConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Set;
/**
* 配置管理控制器
*/
@RestController
@RequestMapping("/config")
@RequiredArgsConstructor
public class ConfigController {
private final UserServiceConfig userServiceConfig;
private final ContextRefresher contextRefresher;
/**
* 获取当前配置
*/
@GetMapping("/current")
public UserServiceConfig getCurrentConfig() {
return userServiceConfig;
}
/**
* 手动刷新配置
*/
@PostMapping("/refresh")
public Set<String> refreshConfig() {
return contextRefresher.refresh();
}
}
5.6 配置加密
1. 加密配置
生成密钥
application.yml
spring:
cloud:
config:
server:
encrypt:
enabled: true
# 对称加密
encrypt:
key: myEncryptionKey123456
# 非对称加密(推荐生产环境)
# encrypt:
# key-store:
# location: classpath:config-server.jks
# password: keystorepass
# alias: config-server-key
# secret: keypass
加密工具类
EncryptionUtil.java
package com.example.configserver.util;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.security.crypto.keygen.KeyGenerators;
/**
* 配置加密工具类
*/
public class EncryptionUtil {
private static final String ENCRYPTION_KEY = "myEncryptionKey123456";
/**
* 加密文本
*/
public static String encrypt(String plainText) {
String salt = KeyGenerators.string().generateKey();
TextEncryptor encryptor = Encryptors.text(ENCRYPTION_KEY, salt);
return salt + encryptor.encrypt(plainText);
}
/**
* 解密文本
*/
public static String decrypt(String encryptedText) {
String salt = encryptedText.substring(0, 16);
String encrypted = encryptedText.substring(16);
TextEncryptor encryptor = Encryptors.text(ENCRYPTION_KEY, salt);
return encryptor.decrypt(encrypted);
}
public static void main(String[] args) {
// 加密示例
String password = "mySecretPassword";
String encrypted = encrypt(password);
System.out.println("Encrypted: " + encrypted);
String decrypted = decrypt(encrypted);
System.out.println("Decrypted: " + decrypted);
}
}
2. 使用加密配置
加密敏感配置
# 使用Config Server的加密端点
curl -X POST http://config-admin:config-password@localhost:8888/encrypt \
-H "Content-Type: text/plain" \
-d "mySecretPassword"
# 返回加密后的值
AQA1234567890abcdef...
在配置文件中使用
# 使用{cipher}前缀标识加密值
spring:
datasource:
password: '{cipher}AQA1234567890abcdef...'
user:
service:
jwt:
secret: '{cipher}AQB9876543210fedcba...'
5.7 配置监听与自动刷新
1. Spring Cloud Bus
添加依赖
pom.xml
<!-- Spring Cloud Bus -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
配置消息总线
application.yml
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
cloud:
bus:
enabled: true
refresh:
enabled: true
env:
enabled: true
management:
endpoints:
web:
exposure:
include: bus-refresh,bus-env
2. Git Webhook自动刷新
Webhook控制器
WebhookController.java
package com.example.configserver.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* Git Webhook控制器
*/
@RestController
@RequestMapping("/webhook")
@RequiredArgsConstructor
@Slf4j
public class WebhookController {
private final ApplicationEventPublisher publisher;
/**
* GitHub Webhook
*/
@PostMapping("/github")
public String githubWebhook(@RequestBody Map<String, Object> payload) {
log.info("Received GitHub webhook: {}", payload);
// 检查是否是配置文件变更
if (isConfigChange(payload)) {
// 发布刷新事件
publisher.publishEvent(new RefreshRemoteApplicationEvent(
this, "config-server", "**"));
log.info("Configuration refresh event published");
return "Configuration refreshed";
}
return "No configuration changes detected";
}
/**
* GitLab Webhook
*/
@PostMapping("/gitlab")
public String gitlabWebhook(@RequestBody Map<String, Object> payload) {
log.info("Received GitLab webhook: {}", payload);
// 类似GitHub的处理逻辑
if (isConfigChange(payload)) {
publisher.publishEvent(new RefreshRemoteApplicationEvent(
this, "config-server", "**"));
log.info("Configuration refresh event published");
return "Configuration refreshed";
}
return "No configuration changes detected";
}
private boolean isConfigChange(Map<String, Object> payload) {
// 检查提交中是否包含配置文件变更
// 这里简化处理,实际应该检查具体的文件路径
return true;
}
}
3. 配置变更监听
配置变更事件监听器
ConfigChangeListener.java
package com.example.userservice.listener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.Set;
/**
* 配置变更事件监听器
*/
@Component
@Slf4j
public class ConfigChangeListener {
/**
* 监听环境变更事件
*/
@EventListener
public void handleEnvironmentChange(EnvironmentChangeEvent event) {
Set<String> changedKeys = event.getKeys();
log.info("Configuration changed, keys: {}", changedKeys);
// 处理特定配置的变更
for (String key : changedKeys) {
if (key.startsWith("user.service.jwt")) {
log.info("JWT configuration changed, key: {}", key);
// 重新初始化JWT相关组件
reinitializeJwtComponents();
} else if (key.startsWith("user.service.email")) {
log.info("Email configuration changed, key: {}", key);
// 重新初始化邮件相关组件
reinitializeEmailComponents();
}
}
}
private void reinitializeJwtComponents() {
// 重新初始化JWT组件的逻辑
log.info("Reinitializing JWT components...");
}
private void reinitializeEmailComponents() {
// 重新初始化邮件组件的逻辑
log.info("Reinitializing email components...");
}
}
5.8 多环境配置管理
1. 环境配置策略
配置文件命名规范
{application}-{profile}.yml
示例:
- user-service.yml # 默认配置
- user-service-dev.yml # 开发环境
- user-service-test.yml # 测试环境
- user-service-staging.yml # 预发布环境
- user-service-prod.yml # 生产环境
配置优先级
- 特定环境的应用配置:
{application}-{profile}.yml
- 应用默认配置:
{application}.yml
- 特定环境的全局配置:
application-{profile}.yml
- 全局默认配置:
application.yml
2. 环境隔离配置
开发环境配置
user-service-dev.yml
# 开发环境配置
spring:
datasource:
url: jdbc:mysql://dev-db:3306/user_service_dev
username: dev_user
password: '{cipher}dev_encrypted_password'
redis:
host: dev-redis
port: 6379
database: 0
jpa:
hibernate:
ddl-auto: update
show-sql: true
# 开发环境特定配置
user:
service:
captcha:
enabled: false # 开发环境禁用验证码
email:
mock: true # 使用模拟邮件发送
# 日志配置
logging:
level:
com.example: DEBUG
org.hibernate.SQL: DEBUG
测试环境配置
user-service-test.yml
# 测试环境配置
spring:
datasource:
url: jdbc:mysql://test-db:3306/user_service_test
username: test_user
password: '{cipher}test_encrypted_password'
redis:
host: test-redis
port: 6379
database: 1
jpa:
hibernate:
ddl-auto: validate
show-sql: false
# 测试环境特定配置
user:
service:
captcha:
enabled: true
length: 4
email:
enabled: true
mock: false
# 日志配置
logging:
level:
com.example: INFO
org.hibernate.SQL: WARN
生产环境配置
user-service-prod.yml
# 生产环境配置
spring:
datasource:
url: jdbc:mysql://prod-db-cluster:3306/user_service_prod
username: prod_user
password: '{cipher}prod_encrypted_password'
hikari:
maximum-pool-size: 50
minimum-idle: 10
redis:
cluster:
nodes:
- prod-redis-1:6379
- prod-redis-2:6379
- prod-redis-3:6379
password: '{cipher}redis_cluster_password'
jpa:
hibernate:
ddl-auto: none
show-sql: false
# 生产环境特定配置
user:
service:
captcha:
enabled: true
length: 6
expire-time: 300
email:
enabled: true
mock: false
smtp:
host: smtp.prod.example.com
port: 587
username: noreply@example.com
password: '{cipher}prod_email_password'
# 日志配置
logging:
level:
com.example: WARN
org.hibernate.SQL: ERROR
file:
name: /var/log/user-service/application.log
max-size: 100MB
max-history: 30
3. 配置管理最佳实践
配置分层管理
ConfigurationManager.java
package com.example.userservice.config;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Arrays;
/**
* 配置管理器
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class ConfigurationManager {
private final Environment environment;
@PostConstruct
public void logConfiguration() {
String[] activeProfiles = environment.getActiveProfiles();
String[] defaultProfiles = environment.getDefaultProfiles();
log.info("Active profiles: {}", Arrays.toString(activeProfiles));
log.info("Default profiles: {}", Arrays.toString(defaultProfiles));
// 记录关键配置信息(不包含敏感信息)
logKeyConfiguration();
}
private void logKeyConfiguration() {
log.info("Database URL: {}",
environment.getProperty("spring.datasource.url"));
log.info("Redis host: {}",
environment.getProperty("spring.redis.host"));
log.info("Captcha enabled: {}",
environment.getProperty("user.service.captcha.enabled"));
log.info("Email enabled: {}",
environment.getProperty("user.service.email.enabled"));
}
/**
* 获取配置值,支持默认值
*/
public String getProperty(String key, String defaultValue) {
return environment.getProperty(key, defaultValue);
}
/**
* 检查是否为生产环境
*/
public boolean isProductionEnvironment() {
return Arrays.asList(environment.getActiveProfiles()).contains("prod");
}
/**
* 检查是否为开发环境
*/
public boolean isDevelopmentEnvironment() {
return Arrays.asList(environment.getActiveProfiles()).contains("dev");
}
}
5.9 总结
核心概念回顾
配置中心的作用:
- 集中管理:统一存储和管理所有服务的配置
- 环境隔离:支持多环境的配置管理
- 动态刷新:支持配置的热更新
- 版本控制:配置变更的版本管理和回滚
- 安全加密:敏感配置的加密存储
Spring Cloud Config组件:
- Config Server:配置服务端,提供配置的存储和访问
- Config Client:配置客户端,从Config Server获取配置
- 配置仓库:存储配置文件的仓库(Git、SVN等)
配置刷新机制:
- 手动刷新:通过Actuator端点手动触发
- 自动刷新:通过Spring Cloud Bus实现自动刷新
- Webhook刷新:通过Git Webhook实现配置变更自动刷新
最佳实践
配置文件组织:
- 使用清晰的命名规范
- 合理的目录结构
- 配置分层管理
- 环境配置隔离
安全管理:
- 敏感配置加密存储
- 配置访问权限控制
- 配置变更审计日志
- 使用HTTPS传输
高可用设计:
- Config Server集群部署
- 配置本地缓存
- 故障转移机制
- 监控和告警
配置管理流程:
- 配置变更审批流程
- 配置版本管理
- 配置回滚机制
- 配置测试验证
注意事项
性能考虑:
- 配置缓存策略
- 网络超时设置
- 批量配置更新
- 配置大小限制
安全防护:
- 配置传输加密
- 访问权限控制
- 敏感信息脱敏
- 配置审计日志
运维管理:
- 配置变更通知
- 配置监控告警
- 配置备份恢复
- 配置文档管理
扩展方向
高级功能:
- 配置模板管理
- 配置继承机制
- 配置验证规则
- 配置A/B测试
集成方案:
- 集成Nacos配置中心
- 集成Apollo配置中心
- 集成Consul配置中心
- 集成Kubernetes ConfigMap
通过本章学习,你应该掌握了Spring Cloud Config的核心概念和实际应用。配置中心是微服务架构中的重要基础设施,合理的配置管理能够显著提升系统的可维护性和运维效率。
下一章我们将学习消息总线,了解如何在微服务架构中实现事件驱动和消息通信。