VortMall 企业版部署指南

VortMall 企业版部署指南

文档说明

适用场景:日活用户(DAU)> 50,000 的生产环境,采用 K8s(ACK Pro 版)部署,云 RDS 高可用 + 只读实例,核心服务 2+ 副本。

读者对象:客户运维人员。

约定

  • <尖括号> 表示需要替换为实际值的占位符
  • 命令示例中 # 开头的行为注释,不需要执行
  • 所有服务器默认使用 Linux(CentOS 7+ / Ubuntu 20+ / Alibaba Cloud Linux 3)

⚠ 密码安全提醒(1/3):本文档涉及多个组件的账号密码。所有密码必须在部署前确定,使用至少 16 位强密码(含大小写字母 + 数字 + 符号),严禁使用默认密码上线。


一、架构总览

                          ┌──────────────────────────────────────────────────────┐
                          │                     公网入口                         │
                          │  域名 → WAF → CLB/ALB → ACK Ingress / 外部 Nginx   │
                          └──────────────────────────┬───────────────────────────┘
                                                     │
              ┌──────────────────────────────────────────────────────────────────┐
              │                 ACK Pro 集群(3 Worker,跨 2 可用区)             │
              │                                                                  │
              │   ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐           │
              │   │ Gateway │  │  Order  │  │ Payment │  │ Product │  ...×17    │
              │   │  ×1~2   │  │   ×2    │  │   ×2    │  │   ×2    │           │
              │   └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘           │
              │        │           │           │           │                     │
              │        └───────────┴───────────┴───────────┘                     │
              │                        Pod 反亲和性                              │
              │                 同一服务的副本分散到不同节点                       │
              └──────────────────────────┬───────────────────────────────────────┘
                                         │ 内网
         ┌───────────────────────────────┼───────────────────────────────┐
         │                               │                               │
   ┌─────┴──────┐              ┌─────────┴──────────┐           ┌───────┴───────┐
   │ 云 RDS      │              │ 中间件 ECS ×2      │           │ 云 Redis 4G  │
   │ MySQL 8.0   │              │ Nacos  RocketMQ    │           │ 主从版        │
   │ 4C8G 高可用 │              │ Seata  XXL-Job     │           └───────────────┘
   │ + 只读实例  │              │ MinIO  EMQX        │
   └─────────────┘              │ ES     Canal       │           ┌───────────────┐
                                │ SkyWalking Logstash│           │ OSS           │
                                └────────────────────┘           │ 图片/文件存储  │
                                                                 └───────────────┘

企业版核心特点

特性说明
ACK Pro 版增强调度能力、安全审计、SLA 保障
跨可用区部署3 台 Worker 分布在 2 个可用区,单 AZ 故障不影响服务
核心服务多副本Gateway、Order、Payment、Product、User 等核心服务 ≥ 2 副本
Pod 反亲和性同一服务的副本调度到不同节点,避免单点故障
RDS 高可用 + 只读实例主从自动切换 + 读写分离,降低主库压力
Redis 4G 主从更大缓存容量,主从高可用
WAF 防护防 SQL 注入、CC 攻击、恶意爬虫
2 台中间件 ECS中间件资源更充裕,互为备份

二、采购清单(阿里云)

产品规格数量用途购买链接
ACK Pro 托管版Pro 版1 集群增强调度、安全审计ACK 控制台
ECS(Worker)8C16G ecs.g7.2xlarge3 台分布在 2 个可用区ECS 购买页
ECS(中间件)8C32G ecs.g7.2xlarge,数据盘 500G ESSD2 台中间件集群ECS 购买页
RDS MySQL 8.04C8G 高可用版 + 200G ESSD1主从自动切换RDS 购买页
RDS 只读实例2C4G1读写分离RDS 购买页
云 Redis4G 标准版(主从)1缓存 + 会话Redis 购买页
OSS标准型 + 低频型1图片/文件存储OSS 控制台
CLB标准型1负载均衡SLB 控制台
EIP固定 10~20Mbps1公网访问
WAF基础版1防 SQL 注入、CC 攻击WAF 控制台

公共配套

  • 域名:至少 1 个(.com / .cn),需完成 ICP 备案(周期 7~20 个工作日),建议采购服务器时同步提交
  • SSL 证书:推荐通配符证书(¥1,000~3,000/年),可覆盖 *.example.com 下所有子域名
  • CDN(按需):商品图片多、全国访问要求高时开通,将 OSS 图片通过 CDN 加速

三、部署前准备

3.1 环境检查清单

检查项要求检查命令
操作系统CentOS 7+ / Ubuntu 20+ / Alibaba Cloud Linux 3cat /etc/os-release
Docker24.0+docker --version
Docker Composev2.20+docker compose version
kubectl1.28+kubectl version --client
可用内存中间件 ECS ≥ 32Gfree -h
磁盘中间件数据盘 ≥ 500G SSDdf -h
时区Asia/Shanghaitimedatectl
文件描述符≥ 65535ulimit -n

3.2 需要提前准备的信息

信息说明示例
ACK Worker 内网 IP3 台 Worker 节点内网 IP10.0.0.1110.0.0.1210.0.0.13
中间件 ECS 内网 IP2 台中间件 ECS 内网 IP10.0.0.2110.0.0.22
中间件 ECS 公网 IP管理访问47.100.xxx.xxx
域名已备案、已做 DNS 解析mall.example.com
SSL 证书文件.pem + .key
RDS 内网连接地址购买后在控制台获取rm-xxxxx.mysql.rds.aliyuncs.com
RDS 只读实例地址购买后在控制台获取rr-xxxxx.mysql.rds.aliyuncs.com
Redis 内网连接地址购买后在控制台获取r-xxxxx.redis.rds.aliyuncs.com
强密码清单见下方密码覆盖范围至少 16 位,含大小写+数字+符号
部署包后端源码 + 前端构建产物由我方提供

密码覆盖范围

组件密码设置方式默认密码
MySQL(云 RDS)购买时在阿里云控制台设置客户自定义
Redis(云 Redis)购买时在阿里云控制台设置客户自定义
Nacos登录后在控制台修改nacos/nacos
XXL-Job登录后在用户管理中修改admin/123456
MinIO修改 docker-compose.yml 中环境变量vortmall/vortmall666
EMQX登录 Dashboard 修改admin/vortmall666
Elasticsearch修改 docker-compose.ymlELASTIC_PASSWORDelastic/vortmall666
Canal修改配置文件canal/canal123
商城管理后台登录后在系统设置中修改admin/123456

3.3 Docker 安装(中间件 ECS 执行)

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
systemctl start docker && systemctl enable docker
docker --version && docker compose version

3.4 操作系统调优(中间件 ECS 执行)

cat >> /etc/sysctl.conf << 'EOF'
vm.max_map_count = 262144
vm.swappiness = 10
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
fs.file-max = 1048576
EOF
sysctl -p

cat >> /etc/security/limits.conf << 'EOF'
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
EOF

3.5 Docker 守护进程优化(中间件 ECS 执行)

mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
  "log-driver": "json-file",
  "log-opts": { "max-size": "50m", "max-file": "3" },
  "storage-driver": "overlay2",
  "live-restore": true,
  "max-concurrent-downloads": 10,
  "registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
EOF
systemctl daemon-reload && systemctl restart docker

四、部署步骤

⚠ 密码安全提醒(2/3):以下步骤中涉及的所有密码,必须使用预先确定的强密码。严禁将默认密码带到生产环境。

步骤 1:配置阿里云 RDS MySQL

登录 RDS 控制台,完成以下配置:

  • 创建数据库账号(建议用户名:vortmall,密码:自定义强密码)
  • 字符集设为 utf8mb4,排序规则 utf8mb4_unicode_ci
  • 白名单添加 ACK Worker 和中间件 ECS 的内网 IP 段(如 10.0.0.0/8
  • 开启慢查询日志(阈值 1s)
  • 记录内网连接地址和端口

验证

mysql -h <RDS内网地址> -P 3306 -u vortmall -p -e "SELECT 1"

预期输出包含 1,表示连接成功。

步骤 2:配置阿里云 Redis

登录 Redis 控制台,完成以下配置:

  • 设置访问密码(强密码)
  • 白名单添加 ACK Worker 和中间件 ECS 的内网 IP 段
  • maxmemory-policy 设为 allkeys-lru
  • 记录内网连接地址和端口

验证

redis-cli -h <Redis内网地址> -p 6379 -a <Redis密码> ping

预期输出 PONG

步骤 3:配置阿里云 OSS

登录 OSS 控制台,完成以下配置:

  • 创建 Bucket(地域与 ECS 一致,权限设为"私有")
  • 创建 RAM 子账号,仅授予该 Bucket 的 OSS 读写权限
  • 记录 AccessKey ID / AccessKey Secret / Bucket 名称 / Endpoint

验证:在 OSS 控制台上传一张测试图片,确认可以通过内网 Endpoint 访问。

步骤 4:准备中间件服务器

将部署文件上传到 2 台中间件 ECS。企业版使用 2 台中间件 ECS,建议分配如下:

中间件 ECS-1中间件 ECS-2
NacosElasticsearch
RocketMQ(NameServer + Broker)Kibana
SeataLogstash
XXL-JobCanal
MinIOSkyWalking OAP
EMQXSkyWalking UI

以上为建议分配,可根据实际资源情况调整。如果负载不高,也可以全部部署在一台上。

分别上传部署文件:

scp -r deployment/DockerCompose/ root@<中间件ECS-1内网IP>:/opt/vortmall/
scp -r deployment/DockerCompose/ root@<中间件ECS-2内网IP>:/opt/vortmall/

步骤 5:修改中间件默认密码

此步骤必须在启动中间件之前完成。

登录中间件 ECS,编辑 /opt/vortmall/DockerCompose/docker-compose.yml,替换以下默认密码:

配置项默认值操作
MINIO_ROOT_USER / MINIO_ROOT_PASSWORDvortmall / vortmall666替换为自定义强密码
ELASTIC_PASSWORDvortmall666替换为自定义强密码

Redis 和 MySQL 使用云服务,不在此处配置。Nacos 和 XXL-Job 的密码在启动后通过 Web 控制台修改(见步骤 9)。

验证grep 确认 docker-compose.yml 中不再包含 vortmall666

grep -n "vortmall666" /opt/vortmall/DockerCompose/docker-compose.yml

预期无输出。

步骤 6:启动中间件

登录中间件 ECS-1:

ssh root@<中间件ECS-1内网IP>
cd /opt/vortmall/DockerCompose

# 替换 IP 占位符
sed -i "s/{{PUBLIC_IP}}/<中间件ECS-1内网IP>/g" docker-compose.yml
sed -i "s/{{PUBLIC_IP}}/<中间件ECS-1内网IP>/g" rocketMQ/data/broker/conf/broker.conf

# 启动非数据库中间件
docker compose up -d nacos namesrv broker rocketmq-dashboard xxl-job seata-server minio emqx

登录中间件 ECS-2(如需部署 ES 全家桶):

ssh root@<中间件ECS-2内网IP>
cd /opt/vortmall/DockerCompose

sed -i "s/{{PUBLIC_IP}}/<中间件ECS-2内网IP>/g" docker-compose.yml

docker compose up -d es kibana logstash canal-server skywalking-oap skywalking-ui

步骤 7:验证中间件

等待约 2~3 分钟后,逐项检查:

服务验证方式预期
Nacoscurl -s http://<中间件ECS-1内网IP>:8848/nacos/v1/ns/service/listHTTP 200
RocketMQcurl -s http://<中间件ECS-1内网IP>:8080/cluster/list.query包含 broker 信息
XXL-Job浏览器访问 http://<中间件ECS-1内网IP>:8082/xxl-job-admin登录页
MinIOcurl -s http://<中间件ECS-1内网IP>:9000/minio/health/liveHTTP 200
EMQX浏览器访问 http://<中间件ECS-1内网IP>:18083Dashboard 页面
EScurl -s -u elastic:<ES密码> http://<中间件ECS-2内网IP>:9200/_cluster/health包含 status 字段

全部验证通过后再进入下一步。如果某项失败,执行 docker compose ps 检查对应容器状态和日志。

步骤 8:初始化数据库

mysql -h <RDS内网地址> -P 3306 -u vortmall -p --default-character-set=utf8mb4 < db/version/mysql/demo.sql

初次体验使用 demo.sql(含演示数据),正式商用使用 pure.sql(空库)。

验证(应有 15 个 vortmall_* 数据库):

mysql -h <RDS内网地址> -P 3306 -u vortmall -p -e "
  SELECT TABLE_SCHEMA, COUNT(*) AS '表数量'
  FROM information_schema.TABLES
  WHERE TABLE_SCHEMA LIKE 'vortmall_%'
  GROUP BY TABLE_SCHEMA;
"

步骤 9:修改中间件 Web 控制台默认密码

组件访问地址默认账号操作
Nacoshttp://<中间件ECS-1内网IP>:8848/nacosnacos/nacos登录后修改密码
XXL-Jobhttp://<中间件ECS-1内网IP>:8082/xxl-job-adminadmin/123456登录 → 用户管理 → 修改密码
EMQXhttp://<中间件ECS-1内网IP>:18083admin/vortmall666登录 Dashboard 修改密码

验证:用新密码重新登录以上控制台,确认均可正常访问。

步骤 10:配置 Nacos

  1. 登录 http://<中间件ECS-1内网IP>:8848/nacos
  2. 左侧菜单 → 命名空间 → 新建命名空间:
    • 命名空间 ID:public
    • 命名空间名:VortMall
  3. 切换到 public 命名空间 → 配置管理 → 配置列表 → 创建配置:

Data IDdatasource-multiple.yml,Group:DEFAULT_GROUP,格式:YAML

spring:
  datasource:
    dynamic:
      primary: master
      strict: true
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://<RDS内网地址>:3306/${vortmall.datasource.db-name}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
          username: <数据库用户名>
          password: <数据库密码>

${vortmall.datasource.db-name} 是变量,每个服务自动填入自己的库名,不需要替换。只需将 <RDS内网地址><数据库用户名><数据库密码> 替换为实际值。

验证:在 Nacos 配置列表中,public 命名空间下能看到 datasource-multiple.yml 配置。

步骤 11:配置 XXL-Job

  1. 登录 http://<中间件ECS-1内网IP>:8082/xxl-job-admin
  2. 确认执行器管理页面可正常访问
  3. 后端服务启动后,执行器会自动注册

验证:XXL-Job 管理后台可正常登录,页面无报错。

步骤 12:构建镜像

# 构建全部后端镜像(17 个)
cd deployment/k8s
bash build.sh

# 构建前端镜像
cd <项目根目录>
docker build -f deployment/docker/frontend/Dockerfile -t vortmall/vortmall-frontend:latest .

验证

docker images | grep vortmall

预期列出 18 个镜像(17 个后端 + 1 个前端)。

步骤 13:推送镜像到阿里云 ACR

先在 ACR 控制台 创建命名空间和镜像仓库,然后推送:

# 登录 ACR
docker login registry.cn-hangzhou.aliyuncs.com -u <阿里云账号>

# 推送后端镜像
cd deployment/k8s
REGISTRY=registry.cn-hangzhou.aliyuncs.com/<命名空间> TAG=v1.0.0 bash build.sh --push

# 推送前端镜像
docker tag vortmall/vortmall-frontend:latest registry.cn-hangzhou.aliyuncs.com/<命名空间>/vortmall-frontend:v1.0.0
docker push registry.cn-hangzhou.aliyuncs.com/<命名空间>/vortmall-frontend:v1.0.0

cn-hangzhou 替换为你的 ACR 所在地域,<命名空间> 替换为你在 ACR 创建的命名空间。

验证:在 ACR 控制台的镜像仓库中,确认 18 个镜像均已上传。

步骤 14:修改 ConfigMap

编辑 deployment/k8s/configmap.yaml,将所有连接信息改为实际值:

data:
  NACOS_ADDR: "<中间件ECS-1内网IP>:8848"
  NACOS_NAMESPACE: "public"
  DB_HOST: "<RDS内网地址>"
  DB_PORT: "3306"
  DB_USERNAME: "<数据库用户名>"
  DB_PASSWORD: "<数据库密码>"
  REDIS_HOST: "<Redis内网地址>"
  REDIS_PORT: "6379"
  REDIS_PASSWORD: "<Redis密码>"
  ROCKETMQ_NAMESRV: "<中间件ECS-1内网IP>:9876"
  SEATA_ADDR: "<中间件ECS-1内网IP>:8091"
  XXLJOB_ADDR: "http://<中间件ECS-1内网IP>:8082/xxl-job-admin"
  MINIO_ENDPOINT: "http://<中间件ECS-1内网IP>:9000"
  MINIO_ACCESS_KEY: "<MinIO AccessKey>"
  MINIO_SECRET_KEY: "<MinIO SecretKey>"
  EMQX_HOST: "<中间件ECS-1内网IP>"
  ES_HOST: "<中间件ECS-2内网IP>"
  ES_PORT: "9200"
  ES_PASSWORD: "<ES密码>"
  SW_AGENT_COLLECTOR_BACKEND_SERVICES: "<中间件ECS-2内网IP>:11800"
  LOGSTASH_HOST: "<中间件ECS-2内网IP>"
  LOGSTASH_PORT: "5001"
  JAVA_OPTS: "-XX:InitialRAMPercentage=25.0 -XX:MaxRAMPercentage=60.0 -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError"
  TZ: "Asia/Shanghai"

验证:确认文件中不再包含未替换的占位符:

grep -n "<" deployment/k8s/configmap.yaml | grep -v "#"

步骤 15:修改服务镜像地址

将所有服务 YAML 中的镜像地址改为 ACR 私有仓库地址:

cd deployment/k8s/services
sed -i 's|image: vortmall/|image: registry.cn-hangzhou.aliyuncs.com/<命名空间>/|g' *.yaml

验证

grep "image:" deployment/k8s/services/*.yaml

预期所有镜像地址以 registry.cn-hangzhou.aliyuncs.com/<命名空间>/ 开头。

步骤 16:K8s 部署与验证

cd deployment/k8s

# 一键部署
bash deploy.sh

# 等待全部 Pod 就绪(超时 5 分钟)
kubectl wait --for=condition=Ready pods --all -n vortmall --timeout=300s

# 查看状态
bash deploy.sh --status

验证

kubectl get pods -n vortmall

所有 Pod 应为 Running 状态,重启次数为 0。

Pod 异常时的快速排查:

# 查看事件
kubectl describe pod <pod名称> -n vortmall

# 查看日志
kubectl logs <pod名称> -n vortmall --tail=200
状态常见原因解决
ImagePullBackOff镜像地址或仓库凭证错误检查镜像地址和 ACR 拉取凭证
CrashLoopBackOff应用启动失败(通常连不上中间件)查日志,检查 ConfigMap 地址
Pending节点资源不足增加节点或降低 requests
OOMKilled内存不足调高 resources.limits.memory

步骤 17:核心服务扩到 2+ 副本 ★

以下步骤 17~19 为企业版独有。

确认步骤 16 所有服务正常运行后,将核心服务副本数扩到 2:

for svc in gateway order payment product user; do
  kubectl scale deployment/vortmall-biz-${svc} -n vortmall --replicas=2 2>/dev/null
  kubectl scale deployment/vortmall-${svc} -n vortmall --replicas=2 2>/dev/null
done

验证

kubectl get deployment -n vortmall | grep -E "gateway|order|payment|product|user"

预期 READY 列显示 2/2。如果副本未就绪,检查节点资源是否充足:

kubectl top nodes

步骤 18:配置 Pod 反亲和性 ★

在核心服务的 YAML 中添加 Pod 反亲和性配置,使同一服务的多个副本分散到不同节点,避免单节点故障导致服务不可用。

vortmall-biz-order 为例,编辑 deployment/k8s/services/vortmall-biz-order.yaml,在 spec.template.spec 下添加:

spec:
  template:
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app: vortmall-biz-order
                topologyKey: kubernetes.io/hostname

对以下核心服务重复上述操作(注意修改 matchLabels.app 为对应服务名):

服务 YAMLmatchLabels.app
vortmall-gateway.yamlvortmall-gateway
vortmall-biz-order.yamlvortmall-biz-order
vortmall-biz-payment.yamlvortmall-biz-payment
vortmall-biz-product.yamlvortmall-biz-product
vortmall-biz-user.yamlvortmall-biz-user

修改完成后重新 apply:

cd deployment/k8s/services
kubectl apply -f vortmall-gateway.yaml
kubectl apply -f vortmall-biz-order.yaml
kubectl apply -f vortmall-biz-payment.yaml
kubectl apply -f vortmall-biz-product.yaml
kubectl apply -f vortmall-biz-user.yaml

验证:确认同一服务的两个 Pod 分布在不同节点上:

kubectl get pods -n vortmall -o wide | grep -E "gateway|order|payment|product|user"

预期同一服务的 2 个 Pod 在 NODE 列显示不同的节点名。

步骤 19:配置 RDS 只读实例 ★

登录 RDS 控制台,为主实例创建只读实例:

  • 规格:2C4G
  • 确认只读实例与主实例在同一 VPC
  • 记录只读实例的内网连接地址

RDS 只读实例会自动与主实例保持数据同步。可以在应用中对读请求使用只读实例地址,以降低主库压力。

在 Nacos 的 datasource-multiple.yml 配置中添加只读数据源(public 命名空间):

spring:
  datasource:
    dynamic:
      primary: master
      strict: true
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://<RDS主实例内网地址>:3306/${vortmall.datasource.db-name}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
          username: <数据库用户名>
          password: <数据库密码>
        slave:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://<RDS只读实例内网地址>:3306/${vortmall.datasource.db-name}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
          username: <数据库用户名>
          password: <数据库密码>

配置发布后,应用会自动从 Nacos 拉取新配置。需要逐个重启业务服务使读写分离生效:

kubectl rollout restart deployment -n vortmall

验证

# 确认所有服务重启完成
kubectl rollout status deployment -n vortmall --timeout=300s

# 检查服务日志,确认数据源加载成功
kubectl logs -l app=vortmall-biz-order -n vortmall --tail=50 | grep -i "datasource"

五、域名与 HTTPS

方案一:外部 Nginx(推荐)

upstream vortmall_frontend {
    server <Worker节点1内网IP>:30080 max_fails=3 fail_timeout=30s;
    server <Worker节点2内网IP>:30080 max_fails=3 fail_timeout=30s;
    server <Worker节点3内网IP>:30080 max_fails=3 fail_timeout=30s;
    keepalive 64;
}

server {
    listen 80;
    server_name <域名>;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name <域名>;

    ssl_certificate     /etc/nginx/ssl/<域名>.pem;
    ssl_certificate_key /etc/nginx/ssl/<域名>.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;

    client_max_body_size 100m;

    location / {
        proxy_pass http://vortmall_frontend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Connection "";
    }

    location /ws {
        proxy_pass http://vortmall_frontend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 3600s;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|webp|avif)$ {
        proxy_pass http://vortmall_frontend;
        expires 7d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
}

方案二:K8s Ingress(ACK 原生)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: vortmall-ingress
  namespace: vortmall
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "100m"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - <域名>
      secretName: vortmall-tls
  rules:
    - host: <域名>
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: vortmall-frontend
                port:
                  number: 80

创建 TLS Secret:

kubectl create secret tls vortmall-tls --cert=<域名>.pem --key=<域名>.key -n vortmall

路由映射

前端容器内部已处理全部路由,外层代理不需要按路径拆分:

URL 路径对应页面
https://<域名>/PC 商城(Nuxt 3)
https://<域名>/admin管理后台(Vue 3)
https://<域名>/mobileH5 移动端(UniApp)
https://<域名>/api/*前台 API → Gateway
https://<域名>/adminapi/*后台 API → Gateway

六、部署验证

6.1 中间件连通性

检查项方法预期
MySQLmysql -h <RDS内网地址> -u vortmall -p -e "SELECT 1"返回 1
Redisredis-cli -h <Redis内网地址> -a <密码> pingPONG
Nacos 控制台浏览器 http://<中间件ECS-1内网IP>:8848/nacos能登录
Nacos 服务数控制台 → 服务列表(public 命名空间)≥ 17 个服务已注册
RocketMQcurl -s http://<中间件ECS-1内网IP>:8080/cluster/list.query包含 broker 信息

6.2 服务健康

kubectl get pods -n vortmall

所有服务应为 Running,重启次数为 0。核心服务副本数应为 2。

6.3 前端页面

页面地址预期
PC 商城https://<域名>/页面正常渲染
管理后台https://<域名>/admin登录页正常显示
H5 移动端https://<域名>/mobile页面正常渲染

6.4 API 接口

curl -s https://<域名>/api/actuator/health

预期输出:{"status":"UP"}

6.5 企业版专项验证

检查项方法预期
多副本kubectl get deploy -n vortmall | grep -E "gateway|order|payment|product|user"READY 列显示 2/2
反亲和性kubectl get pods -n vortmall -o wide | grep order2 个 Pod 在不同节点
只读实例mysql -h <只读实例地址> -u vortmall -p -e "SELECT 1"返回 1

6.6 一键验证脚本

# 验证中间件
bash verify-deployment.sh <中间件ECS-1内网IP>

# 验证全链路
bash verify-deployment.sh <域名>

七、安全加固

部署验证通过后、正式上线前必须完成。

⚠ 密码安全提醒(3/3):以下是最终安全检查。确认所有默认密码已修改,所有敏感端口已关闭,WAF 已开启。

7.1 密码最终确认

组件默认密码确认状态
MySQL(云 RDS)客户自设☐ 已设置强密码
Redis(云 Redis)客户自设☐ 已设置强密码
MinIOvortmall/vortmall666☐ 已修改
EMQXadmin/vortmall666☐ 已修改
Nacosnacos/nacos☐ 已修改
XXL-Jobadmin/123456☐ 已修改
ESelastic/vortmall666☐ 已修改
Canalcanal/canal123☐ 已修改
商城管理后台admin/123456☐ 已修改

修改密码后,同步更新 ConfigMap / Nacos 配置中对应的连接信息,并重启相关服务。

7.2 网络隔离(安全组)

公网入方向(仅开放必要端口):

端口来源说明
80 / 4430.0.0.0/0HTTP / HTTPS
22办公 IP 段SSH(限定来源)

内网入方向

端口来源说明
全部VPC 网段(如 10.0.0.0/8)内网服务互通

中间件端口(3306、6379、8848、9876 等)绝不对公网开放。

7.3 Nginx 安全加固

# 隐藏版本号
server_tokens off;

# API 限速
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
location /api {
    limit_req zone=api burst=60 nodelay;
    proxy_pass http://vortmall_frontend;
}

# 拦截非预期 Host
server {
    listen 80 default_server;
    listen 443 ssl default_server;
    ssl_certificate     /etc/nginx/ssl/<域名>.pem;
    ssl_certificate_key /etc/nginx/ssl/<域名>.key;
    return 444;
}

7.4 WAF 配置(企业版)

登录 WAF 控制台,完成以下配置:

接入配置

  • 将域名 CNAME 解析到 WAF 提供的防护地址
  • 源站地址填写 CLB/SLB 的公网 IP

防护策略

防护项建议配置说明
Web 应用防护开启,规则引擎「严格模式」防 SQL 注入、XSS、命令注入等 OWASP Top 10 攻击
CC 安全防护开启,紧急模式阈值建议 1000 QPS防 CC 攻击导致后端过载
扫描防护开启防自动化扫描工具探测
IP 黑名单按需配置封禁已知恶意 IP
区域封禁按需配置如仅面向国内市场,可封禁海外访问

验证

# 测试 SQL 注入防护(应被 WAF 拦截)
curl -s "https://<域名>/api/test?id=1' OR '1'='1"

预期返回 WAF 拦截页面或 403 状态码,而非正常 API 响应。


八、日常运维

8.1 常用操作

操作命令
查看日志kubectl logs -f deploy/vortmall-biz-order -n vortmall
最后 200 行kubectl logs --tail=200 <pod名称> -n vortmall
重启单个服务kubectl rollout restart deploy/vortmall-biz-order -n vortmall
重启全部kubectl rollout restart deploy -n vortmall
扩缩容kubectl scale deploy/vortmall-biz-order --replicas=3 -n vortmall
资源占用kubectl top pods -n vortmall
进入容器kubectl exec -it <pod名称> -n vortmall -- sh

8.2 版本升级(滚动更新)

企业版核心服务有 2+ 副本,使用滚动更新策略,可实现零停机升级:

# 1. 备份数据库(通过 RDS 控制台或手动)
mysqldump -h <RDS内网地址> -u vortmall -p --all-databases --single-transaction --quick | gzip > backup_$(date +%Y%m%d).sql.gz

# 2. 执行增量 SQL(如有)
mysql -h <RDS内网地址> -u vortmall -p < db/update/update.sql

# 3. 构建新版本镜像并推送
cd deployment/k8s
REGISTRY=registry.cn-hangzhou.aliyuncs.com/<命名空间> TAG=v1.1.0 bash build.sh --push

# 4. 滚动更新单个服务
kubectl set image deployment/vortmall-biz-order \
  vortmall-biz-order=registry.cn-hangzhou.aliyuncs.com/<命名空间>/vortmall-biz-order:v1.1.0 \
  -n vortmall

# 5. 监控更新进度
kubectl rollout status deployment/vortmall-biz-order -n vortmall

8.3 分批发布(企业版推荐)

对于多副本服务,建议按以下顺序分批更新,降低发布风险:

批次服务说明
第 1 批vortmall-biz-file、vortmall-biz-content、vortmall-biz-decoration低风险辅助服务
第 2 批vortmall-biz-product、vortmall-biz-user、vortmall-biz-logistics核心基础服务
第 3 批vortmall-biz-order、vortmall-biz-payment、vortmall-biz-marketing核心交易服务
第 4 批vortmall-gateway、vortmall-auth入口服务(最后更新)

每批更新完成后,验证服务健康再继续下一批:

# 检查第 N 批服务状态
kubectl rollout status deployment/vortmall-biz-order -n vortmall --timeout=120s

# 快速验证 API 可用性
curl -s https://<域名>/api/actuator/health

8.4 滚动更新策略

建议在核心服务的 Deployment YAML 中配置滚动更新策略,确保更新期间始终有可用实例:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  • maxUnavailable: 0:更新期间不允许有不可用的 Pod,确保零停机
  • maxSurge: 1:每次最多多创建 1 个新 Pod

8.5 回滚

# 回滚到上一版本
kubectl rollout undo deployment/vortmall-biz-order -n vortmall

# 查看回滚历史
kubectl rollout history deployment/vortmall-biz-order -n vortmall

# 回滚到指定版本
kubectl rollout undo deployment/vortmall-biz-order -n vortmall --to-revision=2

# 数据库回滚
gunzip < backup_20260327.sql.gz | mysql -h <RDS内网地址> -u vortmall -p

8.6 数据库备份

阿里云 RDS

  • 控制台 → 备份恢复 → 开启自动备份(保留 7 天)
  • 开启 Binlog 备份
  • 只读实例会自动同步主实例数据,无需单独备份

建议额外配置手动备份脚本作为双保险:

mysqldump -h <RDS内网地址> -u vortmall -p --all-databases --single-transaction --quick | gzip > backup_$(date +%Y%m%d).sql.gz

8.7 磁盘清理

docker image prune -a --filter "until=168h" -f
docker builder prune -f
find /opt/vortmall -name "*.log" -mtime +7 -delete

九、常见问题

9.1 Pod CrashLoopBackOff

Java 应用启动失败,通常是连不上中间件。

kubectl logs <pod名称> -n vortmall --tail=50
日志关键词原因解决
Connection refused中间件未启动或地址错误检查 ConfigMap 中的地址
Access denied数据库账号密码错误检查 ConfigMap 中的 DB_USERNAME/DB_PASSWORD
No DataSource数据库未初始化确认 SQL 已导入
Nacos connected failedNacos 地址或命名空间不匹配检查 NACOS_ADDR 和 NACOS_NAMESPACE
OutOfMemoryError内存 limit 太低调高 JAVA_OPTS 或 resources.limits.memory

9.2 前端页面空白 / 404

# 检查前端 Pod 状态
kubectl get pods -n vortmall -l app=vortmall-frontend

# 检查前端文件是否存在
kubectl exec -it <frontend-pod> -n vortmall -- ls -la /usr/share/nginx/html/admin/

# 检查 API 代理连通性
kubectl exec -it <frontend-pod> -n vortmall -- curl -s http://vortmall-gateway:8000/actuator/health

9.3 Nacos 服务列表为空

# 确认命名空间 ID 一致(应为 "public")
curl -s 'http://<中间件ECS-1内网IP>:8848/nacos/v1/console/namespaces'

# 从 Worker 节点测试到 Nacos 的连通性
telnet <中间件ECS-1内网IP> 8848
telnet <中间件ECS-1内网IP> 9848

9.4 MySQL 连接数耗尽

企业版多副本下连接数压力更大,注意监控:

mysql -h <RDS内网地址> -u vortmall -p -e "SHOW STATUS LIKE 'Threads_connected';"
mysql -h <RDS内网地址> -u vortmall -p -e "SHOW PROCESSLIST;"

如需临时调整,在 RDS 控制台修改参数 max_connections

9.5 Pod 反亲和性未生效

如果同一服务的两个 Pod 仍在同一节点:

# 检查节点资源
kubectl top nodes

# 检查 Pod 调度事件
kubectl describe pod <pod名称> -n vortmall | grep -A5 "Events"

常见原因:节点数不足(至少需要 2 个可调度节点)。preferredDuringSchedulingIgnoredDuringExecution 是软约束,资源不足时允许调度到同一节点。


附录 A:端口速查表

中间件端口

服务端口说明
MySQL(云 RDS)3306数据库
Redis(云 Redis)6379缓存
Nacos8848, 9848配置中心 + 服务发现
RocketMQ NameServer9876MQ 名称服务
RocketMQ Broker10909, 10911, 10912MQ Broker
RocketMQ Dashboard8080MQ 管理界面
XXL-Job Admin8082任务调度
Seata7091, 8091分布式事务
MinIO9000 (API), 9001 (Console)对象存储
EMQX1883 (MQTT), 18083 (Dashboard)消息
ES9200, 9300搜索引擎
Kibana5601ES 可视化
Logstash5001, 5044日志收集
Canal11111, 11112数据同步
SkyWalking OAP11800, 12800链路追踪
SkyWalking UI18080链路追踪界面

应用服务端口

服务HTTP 端口XXL-Job 端口K8s NodePort
vortmall-frontend80-30080
vortmall-gateway8000-30800
vortmall-auth8001--
vortmall-biz-product19901--
vortmall-biz-payment1990219702-
vortmall-biz-system19903--
vortmall-biz-marketing19904--
vortmall-biz-order1990519705-
vortmall-biz-content19906--
vortmall-biz-organize19907--
vortmall-biz-logistics19908--
vortmall-biz-aftersales19909--
vortmall-biz-distribution19910--
vortmall-biz-decoration19911--
vortmall-biz-message19912--
vortmall-biz-user19913--
vortmall-biz-file19914--
vortmall-biz-pos19915--

附录 B:服务列表

服务注册名数据库说明
Gatewayvortmall-gateway-API 网关
Authvortmall-auth-认证授权
Productvortmall-biz-productvortmall_product商品、分类、品牌、规格
Paymentvortmall-biz-paymentvortmall_payment支付、退款
Systemvortmall-biz-systemvortmall_system系统配置、菜单、权限
Marketingvortmall-biz-marketingvortmall_marketing营销、优惠券、满减
Ordervortmall-biz-ordervortmall_order订单、购物车、结算
Contentvortmall-biz-contentvortmall_content文章、公告
Organizevortmall-biz-organizevortmall_organize组织架构、店铺
Logisticsvortmall-biz-logisticsvortmall_logistics物流、运费模板
Aftersalesvortmall-biz-aftersalesvortmall_aftersales售后、退货
Distributionvortmall-biz-distributionvortmall_distribution分销
Decorationvortmall-biz-decorationvortmall_decoration页面装修
Messagevortmall-biz-messagevortmall_message消息、通知、短信
Uservortmall-biz-uservortmall_user用户、会员
Filevortmall-biz-filevortmall_file文件上传
POSvortmall-biz-posvortmall_pos收银台、门店
VortMall 企业版部署指南
请输入搜索内容
大纲
VortMall 企业版部署指南
文档说明
一、架构总览
二、采购清单(阿里云)
三、部署前准备
3.1 环境检查清单
3.2 需要提前准备的信息
3.3 Docker 安装(中间件 ECS 执行)
3.4 操作系统调优(中间件 ECS 执行)
3.5 Docker 守护进程优化(中间件 ECS 执行)
四、部署步骤
步骤 1:配置阿里云 RDS MySQL
步骤 2:配置阿里云 Redis
步骤 3:配置阿里云 OSS
步骤 4:准备中间件服务器
步骤 5:修改中间件默认密码
步骤 6:启动中间件
步骤 7:验证中间件
步骤 8:初始化数据库
步骤 9:修改中间件 Web 控制台默认密码
步骤 10:配置 Nacos
步骤 11:配置 XXL-Job
步骤 12:构建镜像
步骤 13:推送镜像到阿里云 ACR
步骤 14:修改 ConfigMap
步骤 15:修改服务镜像地址
步骤 16:K8s 部署与验证
步骤 17:核心服务扩到 2+ 副本 ★
步骤 18:配置 Pod 反亲和性 ★
步骤 19:配置 RDS 只读实例 ★
五、域名与 HTTPS
方案一:外部 Nginx(推荐)
方案二:K8s Ingress(ACK 原生)
路由映射
六、部署验证
6.1 中间件连通性
6.2 服务健康
6.3 前端页面
6.4 API 接口
6.5 企业版专项验证
6.6 一键验证脚本
七、安全加固
7.1 密码最终确认
7.2 网络隔离(安全组)
7.3 Nginx 安全加固
7.4 WAF 配置(企业版)
八、日常运维
8.1 常用操作
8.2 版本升级(滚动更新)
8.3 分批发布(企业版推荐)
8.4 滚动更新策略
8.5 回滚
8.6 数据库备份
8.7 磁盘清理
九、常见问题
9.1 Pod CrashLoopBackOff
9.2 前端页面空白 / 404
9.3 Nacos 服务列表为空
9.4 MySQL 连接数耗尽
9.5 Pod 反亲和性未生效
附录 A:端口速查表
中间件端口
应用服务端口
附录 B:服务列表