多环境管理

返回 Spring Cloud

微服务中通常有 dev / test / staging / prod 多套环境,每套环境有独立的数据库、MQ、注册中心地址。多环境管理的目标是:代码不变,配置随环境切换


Spring Profile 基础

# application.yml(公共配置)
spring:
  application:
    name: order-service
 
---
# dev 环境
spring:
  config:
    activate:
      on-profile: dev
  datasource:
    url: jdbc:mysql://dev-db:3306/order
 
---
# prod 环境
spring:
  config:
    activate:
      on-profile: prod
  datasource:
    url: jdbc:mysql://prod-db:3306/order

激活方式:

# JVM 参数
java -jar order-service.jar --spring.profiles.active=prod
 
# 环境变量(容器化首选)
SPRING_PROFILES_ACTIVE=prod

Nacos 多环境隔离

Nacos 用 Namespace + Group 实现环境与业务隔离:

Namespace(环境隔离,互不可见)
  ├── dev(命名空间 ID: dev-ns-id)
  ├── test(命名空间 ID: test-ns-id)
  └── prod(命名空间 ID: prod-ns-id)
      └── Group(业务分组)
              ├── DEFAULT_GROUP
              ├── ORDER_GROUP
              └── USER_GROUP
                  └── 配置文件:order-service.yaml

配置文件命名规则

Nacos Config 自动加载顺序(精度越高越优先):

1. ${spring.application.name}-${profile}.${file-extension}
   → order-service-prod.yaml

2. ${spring.application.name}.${file-extension}
   → order-service.yaml(各环境共享的基础配置)

3. ${spring.application.name}
   → order-service

bootstrap.yml

spring:
  application:
    name: order-service
  profiles:
    active: ${SPRING_PROFILES_ACTIVE:dev}    # 默认 dev,通过环境变量覆盖
  cloud:
    nacos:
      config:
        server-addr: ${NACOS_SERVER:nacos:8848}
        namespace: ${NACOS_NAMESPACE:dev-ns-id}   # 按环境切换命名空间
        group: ORDER_GROUP
        file-extension: yaml
        shared-configs:
          - data-id: common.yaml   # 所有服务共享的公共配置
            group: DEFAULT_GROUP
            refresh: true
      discovery:
        server-addr: ${NACOS_SERVER:nacos:8848}
        namespace: ${NACOS_NAMESPACE:dev-ns-id}
        group: ORDER_GROUP

Docker / K8s 环境变量注入

Docker Compose

services:
  order-service:
    image: order-service:latest
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - NACOS_SERVER=nacos:8848
      - NACOS_NAMESPACE=prod-ns-id
      - DB_PASSWORD=${DB_PASSWORD}   # 从 .env 文件读取,不写死在 compose 里

K8s ConfigMap + Secret

# configmap.yaml(非敏感配置)
apiVersion: v1
kind: ConfigMap
metadata:
  name: order-config
  namespace: production
data:
  SPRING_PROFILES_ACTIVE: "prod"
  NACOS_SERVER: "nacos-headless:8848"
  NACOS_NAMESPACE: "prod-ns-id"
 
---
# secret.yaml(敏感配置)
apiVersion: v1
kind: Secret
metadata:
  name: order-secret
type: Opaque
stringData:
  DB_PASSWORD: "your-db-password"
  REDIS_PASSWORD: "your-redis-password"
# deployment.yaml
spec:
  containers:
    - name: order-service
      envFrom:
        - configMapRef:
            name: order-config
        - secretRef:
            name: order-secret

配置热刷新

// 需要热刷新的 Bean 加 @RefreshScope
@RefreshScope
@RestController
public class FeatureController {
 
    @Value("${feature.newCheckout.enabled:false}")
    private boolean newCheckoutEnabled;
 
    @GetMapping("/checkout")
    public String checkout() {
        return newCheckoutEnabled ? "新版结算" : "旧版结算";
    }
}

触发刷新(修改 Nacos 配置后自动推送,无需手动调用):

  • Nacos Config 默认长轮询,配置变更 1 秒内推送到客户端
  • 也可手动调用:POST /actuator/refresh
  • 全部服务刷新可配合 Spring Cloud Bus(RabbitMQ/Kafka)广播

敏感配置管理

方案适用场景
Nacos Config(加密扩展)国内项目主流,配置中心统一管理
K8s Secret容器化部署,挂载为环境变量或文件
HashiCorp Vault金融级,支持动态凭证、审计、自动轮换
AWS/阿里云 KMS云原生,密钥托管给云厂商

Nacos 配置加密(jasypt)

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
# Nacos 中存储加密值
spring:
  datasource:
    password: ENC(加密后的密文)
 
jasypt:
  encryptor:
    password: ${JASYPT_ENCRYPTOR_PASSWORD}  # 解密密钥从环境变量注入

环境隔离检查清单

  • 各环境使用独立 Nacos 命名空间
  • 各环境服务互相不可见(Namespace 隔离)
  • 数据库连接串通过环境变量注入,不硬编码
  • 密码等敏感配置使用 Secret 或加密存储
  • CI/CD 流水线按分支自动选择部署环境
  • 生产环境关闭 Swagger / Actuator 敏感端点

相关链接

本目录

Spring Boot

架构