架构进阶:从 Docker 环境变量到 Nacos 统一配置中心实战

摘要 :在上篇文章中(从"裸奔"到"装甲":基于 Docker + Spring Boot 的企业级多环境安全架构实战),我们实现了 Spring Boot 配置的"外部化"。但在微服务架构下,分散在各个服务器上的 .env文件依然难以维护。本文将带你完成从"静态环境变量"到"动态配置中心"的跃迁,使用 Nacos 统一管理所有环境配置,并实现配置热更新。


前言:当 .env文件不再够用时

在上一个方案中,我们通过 Docker 的 env_file注入了 .env文件。这在单体应用中非常完美,但当面临以下场景时,它会显得力不从心:

  1. 配置散落 :10 个服务就有 10 个 .env文件,分布在 10 台服务器上。

  2. 重启代价 :修改一个 Redis 地址,必须 docker restart

  3. 无版本管理:谁改了配置?什么时候改的?回滚怎么办?

  4. 安全性焦虑:虽然没进 Git,但运维手里还是握着一堆密码。

Nacos​ 的出现就是为了解决这些问题。它不仅是注册中心,更是配置中心。


第一章:新架构全景图

我们先来看一下引入 Nacos 后的架构变化。

1.1 架构对比

维度 Docker Env 方案 Nacos 方案
存储位置 服务器文件 (.env) Nacos Server 数据库
更新机制 重启容器 实时推送 / 热更新
管理方式 分散管理 统一 Web 控制台
版本控制 自带历史版本与回滚
适用场景 单体应用 微服务 / 分布式

1.2 数据流

复制代码
+-------------------+    推送配置    +-------------------+
|   Nacos Console   |  -----------> |   Nacos Server    |
+-------------------+               +---------+---------+
                                            |
                                            | 监听变更 (Long Polling)
                                            v
                                  +-------------------+
                                  |  Spring Boot App  |
                                  | (Nacos Config Client)|
                                  +-------------------+

第二章:Nacos 环境准备

2.1 使用 1Panel 快速部署 Nacos

如果你在用 1Panel,部署 Nacos 非常简单。

  1. 进入 应用商店 ​ -> 搜索 Nacos

  2. 选择 单机模式(Standalone)。

  3. 设置端口映射(例如 8848)。

  4. 启动。

2.2 初始化命名空间 (Namespace)

为了区分环境,我们在 Nacos 中创建命名空间。

Namespace ID Name 说明
dev 开发环境 开发同学使用
test 测试环境 测试同学使用
prod 生产环境 线上环境

第三章:Spring Boot 接入 Nacos

这是最核心的代码改造环节。

3.1 依赖变更 (pom.xml)

移除或保留原有的 Spring Cloud Alibaba 依赖。

复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3.2 配置文件大挪移

我们要把原来写在 application-dev.yml里的东西,搬到 Nacos 里。

本地只保留一个 bootstrap.yml(优先级最高,用于连接 Nacos)。

复制代码
# bootstrap.yml
spring:
  application:
    name: shiyuan-admin
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
      config:
        server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
        file-extension: yaml
        # 关键:指定命名空间(dev/test/prod)
        namespace: ${NACOS_NAMESPACE:dev}
        # 配置分组
        group: DEFAULT_GROUP
        # 支持动态刷新
        refresh-enabled: true

3.3 Nacos 中的配置内容

在 Nacos 控制台 dev命名空间下,创建配置 shiyuan-admin.yaml

Data ID : shiyuan-admin.yaml

Group : DEFAULT_GROUP

配置内容 (这就是你原来的 application-dev.yml去掉占位符后的版本,但密码等敏感信息依然用占位符,或者直接用真实值放在 Nacos 里更安全):

复制代码
spring:
  datasource:
    dynamic:
      datasource:
        master:
          url: jdbc:mysql://${DB_HOST}:3306/${DB_NAME}?useSSL=false
          username: ${DB_USERNAME}
          password: ${DB_PASSWORD}
  data:
    redis:
      host: ${REDIS_HOST}
      password: ${REDIS_PASSWORD}

# 邮件
mail:
  pass: ${MAIL_PASS}

# 短信
sms:
  blends:
    aliyun:
      access-key-id: ${SMS_ALI_ACCESS_KEY}
      access-key-secret: ${SMS_ALI_SECRET}

注意 :你会发现这里还是有 ${}。这是因为 Nacos 也支持从环境变量读取(推荐),或者你也可以直接在 Nacos 里写死值。


第四章:Docker 与 Nacos 的结合(关键)

现在,我们不再需要把大量的配置塞进 .env,只需要告诉 Spring Boot Nacos 在哪里

4.1 新的 .env文件

.env文件变得非常精简,只负责"引导"应用。

复制代码
# ================== 基础 ==================
CONTAINER_NAME=shiyuan-admin
CODE_DIR=/opt/apps/shiyuan-admin/target
JAVA_APP_PORT=9113

# ================== Nacos 环境 ==================
NACOS_SERVER_ADDR=172.17.0.1:8848  # Docker 网桥地址
NACOS_NAMESPACE=dev

# ================== 敏感信息(仅作为兜底) ==================
# 如果 Nacos 里的配置也用了变量,这里需要提供
DB_PASSWORD=YourStrongPassword
REDIS_PASSWORD=RedisPass

4.2 新的 docker-compose.yml

复制代码
networks:
  1panel-network:
    external: true

services:
  java-app:
    container_name: ${CONTAINER_NAME}
    image: bitnami/java:17
    command: bash /run.sh
    env_file:
      - .env  # 只注入 Nacos 地址和少量敏感变量
    environment:
      - TZ=Asia/Shanghai
      # 这里不再需要 SPRING_PROFILES_ACTIVE,由 Nacos Namespace 控制
    networks:
      - 1panel-network
    ports:
      - ${HOST_IP}:${PANEL_APP_PORT_HTTP}:${JAVA_APP_PORT}
    restart: on-failure:5
    volumes:
      - ${CODE_DIR}:/app
      - ./run.sh:/run.sh
    working_dir: /app

4.3 改造 run.sh(支持 JVM 参数从 Nacos 读取)

虽然配置在 Nacos,但 JVM 参数通常还是在启动时确定。

复制代码
#!/bin/bash
set -e

cd /app

echo "==> Connecting to Nacos: $NACOS_SERVER_ADDR"
echo "==> Namespace: $NACOS_NAMESPACE"

exec java \
  -Xms512m \
  -Xmx1024m \
  -XX:+UseG1GC \
  -XX:+HeapDumpOnOutOfMemoryError \
  -Dspring.cloud.nacos.config.namespace=${NACOS_NAMESPACE} \
  -Dspring.cloud.nacos.server-addr=${NACOS_SERVER_ADDR} \
  -jar shiyuan-admin.jar

第五章:实现"配置热更新"(@RefreshScope)

这是 Nacos 最诱人的功能。

5.1 代码示例

假设你有一个读取 Redis 配置的 Bean:

复制代码
@RestController
@RequestMapping("/config")
@RefreshScope // 核心注解:开启配置刷新
public class ConfigController {

    @Value("${spring.data.redis.host}")
    private String redisHost;

    @GetMapping("/redis-host")
    public String getRedisHost() {
        return "Current Redis Host: " + redisHost;
    }
}

5.2 操作流程

  1. 修改 Nacos 中 shiyuan-admin.yamlspring.data.redis.host

  2. 点击 发布

  3. 无需重启应用 ,再次访问 /config/redis-host,发现值已经变了。


第六章:Nacos 鉴权与安全

Nacos 本身也需要安全加固。

6.1 开启鉴权

在 1Panel 部署 Nacos 时,务必开启鉴权(或手动修改 application.properties):

复制代码
nacos.core.auth.enabled=true
nacos.core.auth.system.type=nacos

6.2 配置 Docker 认证

如果 Nacos 开了鉴权,.env需要增加:

复制代码
NACOS_USERNAME=nacos
NACOS_PASSWORD=YourNacosPassword

并在 bootstrap.yml中配置:

复制代码
spring:
  cloud:
    nacos:
      username: ${NACOS_USERNAME}
      password: ${NACOS_PASSWORD}

第七章:迁移过程中的坑与解决方案

坑 1:配置加载顺序混乱

现象:本地配置覆盖了 Nacos 配置。

解决:记住 Spring Boot 配置优先级(从高到低):

  1. Command Line Arguments (--server.port=8081)

  2. JNDI attributes

  3. Java System Properties (-Dproperty=value)

  4. OS Environment Variables (Docker env)

  5. Nacos Config

  6. application-{profile}.yml

  7. application.yml

  8. @PropertySource

经验 :不要把同样的配置写在 application.yml里,否则会覆盖 Nacos。

坑 2:Nacos 连不上

现象java.net.ConnectException: Connection refused

解决

  • 检查 NACOS_SERVER_ADDR是否是 Docker 容器能访问到的地址。

  • 如果是 1Panel,127.0.0.1可能不行,要用宿主机的局域网 IP 或 Docker 网桥 IP(如 172.17.0.1)。

坑 3:配置回滚

操作:在 Nacos 控制台 -> 配置管理 -> 历史版本 -> 选择版本 -> 回滚。


第八章:最终的安全架构评估

经过这次改造,我们的安全等级再次提升。

资产 存放位置 安全性
代码 Git ⭐⭐⭐⭐⭐ (无密码)
Jar 包 Docker Image ⭐⭐⭐⭐⭐ (无密码)
引导配置 .env(Server) ⭐⭐⭐⭐ (仅 Nacos 地址)
业务配置 Nacos Server ⭐⭐⭐⭐⭐ (有权限控制、审计)
数据库 内网 VPC ⭐⭐⭐⭐⭐

结语

从最初的"密码满天飞",到 Docker 环境变量隔离,再到 Nacos 统一配置中心,我们不仅解决了技术问题,更完成了一次工程思维的升级。

现在的架构优势在于:

  1. 运维友好:运维只管 Nacos,不用碰代码。

  2. 开发友好:开发只看 Git,不用管密码。

  3. 应急高效:改配置不用重启,秒级生效。

  4. 审计合规:谁改了什么,一清二楚。

如果你的项目正在从单体走向微服务,或者正在为配置管理头疼,强烈建议你试试这套方案。

相关推荐
2603_954708311 小时前
微电网分布式电源接入技术的相关国家标准有哪些?
人工智能·分布式·物联网·架构·系统架构·能源
comedate2 小时前
[WSL2] 解决 WSL2 中 Docker 部署的 SearXNG 重启后,localhost 不能用的问题
docker·wsl2·searxng
绝知此事2 小时前
Redis 从入门到精通:Spring Boot 实战三部曲(二)—— 进阶原理与高可用架构
spring boot·redis·架构
Hui Baby2 小时前
K8S自定义API
容器·贪心算法·kubernetes
ai产品老杨2 小时前
突破异构算力与多协议壁垒:基于 Docker+边缘计算的企业级 AI 视频管理平台架构解析
人工智能·docker·边缘计算
炸炸鱼.10 小时前
Kubernetes高级调度02:Taint/Toleration、Cordon/Drain、亲和性与反亲和性完全指南
云原生·容器·kubernetes
hai31524754310 小时前
RISC-V核E203核前向旁路的架构性顽疾
驱动开发·架构·硬件架构·硬件工程·risc-v
意图共鸣10 小时前
意图共鸣科技《认知智能白皮书》——感知与执行分离:认知架构(CA)如何重塑大模型底层结构
人工智能·架构
王莎莎-MinerU11 小时前
MinerU 深度技术解析:从架构原理到生产部署的全面指南
css·人工智能·自然语言处理·架构·ocr·个人开发