SpringBoot配置分环境的标准做法

SpringBoot配置分环境的标准做法

Spring Boot 简化了配置,但日志管理依然需要重视。日志配置、链路追踪、排查思路都是日常开发中会遇到的问题。本文讲实际项目中的日志管理经验。

1. Profile 文件分离

#

文件结构

src/main/resources/
├── application.yml # 公共配置
├── application-dev.yml # 开发环境
├── application-test.yml # 测试环境
└── application-prod.yml # 生产环境

#

application.yml(公共配置)

spring:
profiles:
active: dev # 默认激活 dev

application:
name: my-service

server:
port: 8080

# 日志公共配置
logging:
level:
root: INFO

#

application-dev.yml(开发环境)

spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: root
password: root

redis:
host: localhost
port: 6379
database: 0

# 开发环境打印 SQL
logging:
level:
com.example.mapper: DEBUG

#

application-prod.yml(生产环境)

spring:
datasource:
url: jdbc:mysql://prod-mysql:3306/prod_db
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 50
minimum-idle: 10

redis:
host: prod-redis
port: 6379
password: ${REDIS_PASSWORD}
lettuce:
pool:
max-active: 50

# 生产环境关闭详细日志
logging:
level:
root: WARN
com.example: INFO

2. 激活 Profile

#

方式1:配置文件

spring:
profiles:
active: prod

#

方式2:启动参数

java -jar app.jar --spring.profiles.active=prod

#

方式3:环境变量

export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar

#

方式4:JVM 参数

java -Dspring.profiles.active=prod -jar app.jar

#

方式5:Maven 打包时

<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
mvn clean package -Pprod

3. @Profile 注解

#

Bean 级别控制

@Configuration
public class DataSourceConfig {

@Bean
@Profile("dev")
public DataSource devDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:h2:mem:testdb");
return new HikariDataSource(config);
}

@Bean
@Profile("prod")
public DataSource prodDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://prod:3306/db");
return new HikariDataSource(config);
}
}

#

配置类级别控制

@Profile("dev")
@Configuration
public class DevConfig {
// 只在 dev 环境生效
}

@Profile("!prod") // 非 prod 环境生效
@Configuration
public class NonProdConfig {
// ...
}

@Profile({"dev", "test"}) // 多个 profile
@Configuration
public class DevTestConfig {
// ...
}

4. 多 Profile 组合

spring:
profiles:
active: prod,swagger
# application-swagger.yml
springdoc:
api-docs:
enabled: true
swagger-ui:
enabled: true

5. 配置优先级

Spring Boot 配置的优先级(从高到低):

  1. 命令行参数:--server.port=9000
  2. JVM 系统属性:-Dserver.port=9000
  3. 环境变量:SERVER_PORT=9000
  4. application-{profile}.yml
  5. application.yml
  6. @PropertySource
  7. 默认值

6. 配置中心(Nacos)

#

引入依赖

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

#

bootstrap.yml

spring:
application:
name: my-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
namespace: dev
group: DEFAULT_GROUP
file-extension: yaml

#

Nacos 配置

# Data ID: my-service-dev.yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: root
password: root

7. 敏感配置加密

#

Jasypt

<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
jasypt:
encryptor:
password: ${JASYPT_PASSWORD}

spring:
datasource:
password: ENC(encrypted_password_here)
# 加密
java -cp jasypt.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \
input="real_password" password="secret_key" algorithm=PBEWITHHMACSHA512ANDAES_256

8. 配置验证

#

@Validated + @ConfigurationProperties

@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {

@NotBlank
private String name;

@Min(1)
@Max(100)
private int threadPoolSize = 10;

// getter/setter
}
app:
name: my-app
thread-pool-size: 20

9. 配置热更新

#

@RefreshScope(Spring Cloud)

@RestController
@RefreshScope
public class ConfigController {

@Value("${app.message:default}")
private String message;

@GetMapping("/message")
public String getMessage() {
return message;
}
}
# 刷新配置(无需重启)
curl -X POST http://localhost:8080/actuator/refresh

最佳实践

实践 说明
默认配置 application.yml 放公共、不变的配置
环境配置 application-{env}.yml 放环境相关的配置
敏感信息 使用环境变量或配置中心,不要硬编码
加密 密码等敏感配置使用 Jasypt 加密
验证 使用 @Validated 验证配置项
文档 给 @ConfigurationProperties 字段加注释

总结

方式 适用场景
Profile 文件 简单项目,配置不复杂
@Profile Bean 级别控制
启动参数 临时切换环境
配置中心 微服务,配置集中管理
环境变量 容器化部署,敏感配置

合理管理多环境配置,是保证应用在不同环境稳定运行的基础。

核心要点

  1. 日志级别设置:根据环境设置合适的级别

  2. 日志格式配置:添加 traceId 便于链路追踪

  3. 日志输出:控制台输出和文件输出的配置

  4. 日志归档:设置滚动策略和保留时间

总结

日志是排查问题的生命线,合理配置日志可以提升排查效率。在实际项目中,结合 ELK 等工具搭建日志系统,可以更好地管理和分析日志。


   转载规则


《SpringBoot配置分环境的标准做法》 小乐 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录