VortMall 标准版部署指南
VortMall 标准版部署指南
文档说明
适用场景:日活用户(DAU)1,000 ~ 50,000,推荐档位。适合正式商用、中等流量电商站点。
架构概览:
┌──────────────────────────────────────────────────────────┐
│ 公网入口 │
│ SLB(ALB) + EIP + 域名 + SSL │
└──────────────┬───────────────────────────────┬────────────┘
│ │
┌──────────▼──────────┐ ┌───────────▼──────────┐
│ ACK 托管集群 │ │ 中间件 ECS │
│ (2 Worker 节点) │ │ 8C32G 200G ESSD │
│ │ │ │
│ 17 个微服务容器 │◄──────►│ Nacos / RocketMQ │
│ + 前端 Nginx 容器 │ │ XXL-Job / Seata │
│ │ │ EMQX / MinIO(备选) │
└──────────┬───────────┘ │ ES 全家桶(可选) │
│ └───────────────────────┘
┌──────────▼───────────────────────────────┐
│ 阿里云托管服务 │
│ RDS MySQL 8.0(高可用) + 云 Redis(主从) │
│ OSS(对象存储) │
└──────────────────────────────────────────┘
约定:
<尖括号>表示需替换为实际值的占位符- 命令中
#开头的行为注释,不需要执行 - 所有服务器使用 Linux(CentOS 7+ / Ubuntu 20+ / Alibaba Cloud Linux 3)
[!CAUTION]
安全警告:部署前必须修改所有默认密码!本部署包的中间件和管理后台使用默认密码仅供开发联调,严禁用于生产环境。
请在 步骤 5 按密码对照表逐项修改,并在部署完成后执行 第五章安全加固核查表 确认无遗漏。
未修改默认密码直接上线将导致严重安全风险。
一、采购清单
1.1 服务器与云服务
| 产品 | 规格 | 数量 | 用途 | 购买链接 |
|---|---|---|---|---|
| ACK 托管版 | 基础版(免管理费) | 1 集群 | 容器编排 | ACK 控制台 |
| ECS(Worker) | 4C16G ecs.g7.xlarge,数据盘 50G ESSD | 2 台 | 运行应用服务 | ECS 购买 |
| ECS(中间件) | 8C32G ecs.g7.2xlarge,数据盘 200G ESSD | 1 台 | 非数据库中间件 | ECS 购买 |
| RDS MySQL 8.0 | 2C4G 高可用版 + 100G ESSD | 1 | 业务数据库 | RDS 购买 |
| 云 Redis | 2G 标准版(主从) | 1 | 缓存 + 会话 | Redis 购买 |
| OSS | 标准型,按量 | 1 | 图片 / 文件存储 | OSS 控制台 |
| SLB | 推荐 ALB(应用型) | 1 | ACK Ingress 入口 | SLB 控制台 |
| EIP | 按流量或固定 5Mbps | 1 | 公网访问 | EIP 控制台 |
1.2 公共配套
| 项目 | 说明 | 链接 |
|---|---|---|
| 域名 | 至少 1 个(.com / .cn),需完成 ICP 备案(周期 7~20 个工作日),建议购买服务器时同步提交 | 域名注册 |
| SSL 证书 | 推荐通配符证书(覆盖 *.example.com) | SSL 证书 |
| CDN | 按需开通,加速商品图片和前端静态资源 | CDN 控制台 |
| ACR | 容器镜像服务,用于存储后端 / 前端 Docker 镜像 | ACR 控制台 |
1.3 需要提前准备的信息
部署开始前,请将以下信息收集到一份表格中,后续步骤会频繁引用:
| 信息项 | 说明 | 示例 | 您的值 |
|---|---|---|---|
| 中间件 ECS 内网 IP | 中间件服务器内网地址 | 10.0.0.10 | |
| 中间件 ECS 公网 IP | 中间件管理界面访问(部署期间) | 47.100.xxx.xxx | |
| Worker 节点 IP 段 | ACK Worker 节点 VPC 网段 | 10.0.0.0/16 | |
| RDS 内网地址 | RDS 控制台获取 | rm-xxx.mysql.rds.aliyuncs.com | |
| RDS 端口 | 默认 3306 | 3306 | |
| RDS 账号 | 建议 vortmall | vortmall | |
| RDS 密码 | 强密码(≥16 位,大小写+数字+符号) | ||
| Redis 内网地址 | Redis 控制台获取 | r-xxx.redis.rds.aliyuncs.com | |
| Redis 端口 | 默认 6379 | 6379 | |
| Redis 密码 | 强密码 | ||
| OSS Bucket | 与 ECS 同地域 | vortmall-files | |
| OSS Endpoint | 内网 endpoint | oss-cn-hangzhou-internal.aliyuncs.com | |
| OSS AccessKey ID | RAM 子账号 AK | ||
| OSS AccessKey Secret | RAM 子账号 SK | ||
| 域名 | 已备案 | mall.example.com | |
| SSL 证书文件 | .pem + .key | ||
| ACR 命名空间 | 镜像仓库命名空间 | vortmall-prod | |
| ACR 地域 | 与 ACK 同地域 | cn-hangzhou |
二、部署步骤
步骤 1:配置云 RDS MySQL
1.1 登录 RDS 控制台,进入已购实例
1.2 创建数据库账号:
- 用户名:
vortmall(建议) - 密码:使用强密码(≥16 位,含大小写字母+数字+特殊字符)
- 账号类型:高权限账号
1.3 设置字符集:
- 字符集:
utf8mb4 - 排序规则:
utf8mb4_unicode_ci
1.4 配置白名单:
- 添加 ACK Worker 节点所在 VPC 网段(如
10.0.0.0/16) - 添加中间件 ECS 内网 IP(如
10.0.0.10)
1.5 开启慢查询日志:
- 控制台 → 参数设置 →
slow_query_log= ON long_query_time= 1(秒)
1.6 记录内网连接地址和端口
验证:在中间件 ECS 上执行:
mysql -h <RDS内网地址> -P 3306 -u vortmall -p -e "SELECT 1"
预期输出包含 1。
步骤 2:配置云 Redis
2.1 登录 Redis 控制台,进入已购实例
2.2 设置访问密码(强密码)
2.3 配置白名单(同 RDS,添加 Worker 网段 + 中间件 ECS IP)
2.4 设置淘汰策略:
- 控制台 → 参数设置 →
maxmemory-policy=allkeys-lru
2.5 记录内网连接地址和端口
验证:在中间件 ECS 上执行:
redis-cli -h <Redis内网地址> -p 6379 -a <Redis密码> ping
预期输出:PONG
步骤 3:配置 OSS
3.1 登录 OSS 控制台
3.2 创建 Bucket:
- 地域:与 ECS 相同(如
华东1(杭州)) - 存储类型:标准存储
- 读写权限:私有
- 同地域冗余:推荐开启
3.3 创建 RAM 子账号:
- 登录 RAM 控制台
- 创建用户 → 开启 OpenAPI 调用访问
- 仅授予该 Bucket 的
oss:PutObject、oss:GetObject、oss:DeleteObject、oss:ListObjects权限
3.4 记录以下信息:
| 项目 | 值 |
|---|---|
| Bucket 名称 | <Bucket> |
| 内网 Endpoint | oss-cn-<地域>-internal.aliyuncs.com |
| AccessKey ID | <AK> |
| AccessKey Secret | <SK> |
验证:使用 ossutil 或控制台上传一个测试文件,确认可正常读写。
步骤 4:中间件 ECS 安装 Docker
登录中间件 ECS 服务器,执行以下命令:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
systemctl start docker && systemctl enable docker
验证:
docker --version && docker compose version
预期输出 Docker 24.0+ 和 Docker Compose v2.20+ 版本号。
步骤 5:修改中间件默认密码(启动前必做)
[!WARNING]
此步骤必须在启动中间件之前完成! MySQL 和 Redis 已使用阿里云托管服务(您在步骤 1、2 中已设置密码),以下仅涉及中间件 ECS 上的组件。
5.1 密码对照表
| 组件 | 默认账号 | 默认密码 | 修改位置 | 修改后需同步更新 |
|---|---|---|---|---|
| Nacos | nacos | nacos | 启动后登录控制台修改 | — |
| XXL-Job Admin | admin | 123456 | 启动后登录控制台修改 | — |
| XXL-Job accessToken | — | default_token | xxl-job/config/application.properties 中的 xxl.job.accessToken | K8s ConfigMap 中的 XXLJOB_ACCESS_TOKEN |
| MinIO | vortmall | vortmall666 | docker-compose.yml 中的 MINIO_ROOT_USER / MINIO_ROOT_PASSWORD | K8s ConfigMap 中的 MINIO_ACCESS_KEY / MINIO_SECRET_KEY |
| EMQX | admin | vortmall666 | 启动后登录 Dashboard 修改 | — |
| Elasticsearch | elastic | vortmall666 | docker-compose.yml 中的 ELASTIC_PASSWORD | K8s ConfigMap 中的 ES_PASSWORD |
| Canal | canal | canal123 | MySQL 中修改该用户密码 | Canal 配置文件 |
5.2 修改步骤
MinIO(启动前修改):
cd /opt/vortmall/DockerCompose
# 编辑 docker-compose.yml 找到 MinIO 部分
# 修改 MINIO_ROOT_USER 和 MINIO_ROOT_PASSWORD 为新值
vi docker-compose.yml
Elasticsearch(启动前修改):
# 在 docker-compose.yml 中找到 ES 部分
# 修改 ELASTIC_PASSWORD 为新值
vi docker-compose.yml
XXL-Job accessToken(启动前修改):
vi xxl-job/config/application.properties
# 找到 xxl.job.accessToken=default_token,改为新 Token
Nacos / XXL-Job Admin / EMQX(启动后修改):
这三个组件需在启动后通过 Web 控制台修改密码,将在步骤 6 启动后立即操作。
步骤 6:上传部署文件 + 启动非数据库中间件
6.1 上传部署文件到中间件 ECS:
scp -r deployment/DockerCompose/ root@<中间件ECS内网IP>:/opt/vortmall/
6.2 登录中间件 ECS 并替换 IP 占位符:
ssh root@<中间件ECS内网IP>
cd /opt/vortmall/DockerCompose
sed -i "s/{{PUBLIC_IP}}/<中间件ECS内网IP>/g" docker-compose.yml
sed -i "s/{{PUBLIC_IP}}/<中间件ECS内网IP>/g" rocketMQ/data/broker/conf/broker.conf
6.3 启动核心中间件(不含 MySQL 和 Redis):
docker compose up -d nacos namesrv broker rocketmq-dashboard xxl-job seata-server minio emqx
6.4(可选)启动 ES 全家桶:
docker compose up -d es kibana logstash canal-server skywalking-oap skywalking-ui
6.5 等待约 2 分钟后,立即修改启动后才能改的密码:
修改 Nacos 密码:
- 浏览器打开
http://<中间件IP>:8848/nacos,用nacos/nacos登录 - 右上角 → 修改密码 → 设置新密码
修改 XXL-Job Admin 密码:
- 浏览器打开
http://<中间件IP>:8082/xxl-job-admin,用admin/123456登录 - 用户管理 → 修改 admin 密码
修改 EMQX 密码:
- 浏览器打开
http://<中间件IP>:18083,用admin/vortmall666登录 - 用户管理 → 修改管理员密码
6.6 逐项验证中间件:
| 服务 | 验证方式 | 预期结果 |
|---|---|---|
| Nacos | curl -s http://<中间件IP>:8848/nacos/v1/ns/service/list | HTTP 200 |
| RocketMQ | curl -s http://<中间件IP>:8080/cluster/list.query | 包含 broker 信息 |
| XXL-Job | 浏览器打开 http://<中间件IP>:8082/xxl-job-admin | 能用新密码登录 |
| Seata | curl -s http://<中间件IP>:7091/health | 返回健康状态 |
| MinIO | curl -s http://<中间件IP>:9000/minio/health/live | HTTP 200 |
| EMQX | 浏览器打开 http://<中间件IP>:18083 | 能用新密码登录 |
| ES(如开启) | curl -s -u elastic:<新密码> http://<中间件IP>:9200/_cluster/health | status 为 green 或 yellow |
全部验证通过后再进入下一步。任何一项失败,先执行
docker compose ps检查容器状态,再用docker compose logs <服务名>查看日志。
步骤 7:初始化数据库
7.1 将 SQL 文件从项目目录导入到云 RDS:
mysql -h <RDS内网地址> -P 3306 -u vortmall -p --default-character-set=utf8mb4 < db/version/mysql/pure.sql
正式商用请导入
pure.sql(干净空库)。如需演示数据可导入demo.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;
"
预期输出 15 行,每行对应一个 vortmall_* 数据库。
步骤 8:修改商城管理后台默认管理员密码
数据库初始化后,vortmall_system 库中的管理员账号使用默认密码。请立即修改:
mysql -h <RDS内网地址> -P 3306 -u vortmall -p -e "
USE vortmall_system;
SELECT admin_id, username FROM sys_admin WHERE username = 'admin';
"
确认管理员账号存在后,在系统上线并可访问管理后台后,第一时间登录并修改密码(参见步骤 16 验证环节)。
步骤 9:配置 Nacos
9.1 浏览器打开 http://<中间件IP>:8848/nacos,用修改后的密码登录
9.2 新建命名空间:
- 左侧菜单 → 命名空间 → 新建命名空间
- 命名空间 ID:
public - 命名空间名:
VortMall
9.3 切换到 public 命名空间 → 配置管理 → 配置列表 → 新建配置:
Data ID:datasource-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: <RDS账号>
password: <RDS密码>
${vortmall.datasource.db-name}是 Spring 变量占位符,每个微服务启动时会自动填入自己的库名,不需要替换。只需将<RDS内网地址>、<RDS账号>、<RDS密码>替换为实际值。
验证:在 Nacos 配置列表中,public 命名空间下能看到 datasource-multiple.yml。
步骤 10:XXL-Job 配置确认
10.1 登录 XXL-Job Admin(http://<中间件IP>:8082/xxl-job-admin)
10.2 确认执行器管理页面可正常访问
10.3 确认已在步骤 5 中修改了 accessToken,后续 K8s ConfigMap 中需使用相同的 Token 值
验证:能用新密码正常登录 XXL-Job 控制台。
步骤 11:构建后端镜像 + 推送到阿里云 ACR
11.1 确保本地已安装 JDK 21+、Maven 3.9+、Docker
11.2 登录阿里云 ACR:
docker login --username=<阿里云账号> registry.cn-<地域>.aliyuncs.com
11.3 Maven 打包 + 构建 + 推送:
cd deployment/k8s
REGISTRY=registry.cn-<地域>.aliyuncs.com/<ACR命名空间> TAG=v1.0.0 bash build.sh --push
此命令会自动执行 Maven 打包(
mvn package -DskipTests),然后构建 17 个后端服务镜像并推送到 ACR。整个过程约 10~20 分钟。
验证:登录 ACR 控制台,确认 17 个镜像仓库均有 v1.0.0 标签。
步骤 12:构建前端镜像 + 推送到 ACR
12.1 在项目根目录下确保 public/ 目录包含三套前端构建产物:
public/
├── pc/ # PC 端(Nuxt 3 构建产物)
├── admin/ # 管理后台(Vue 3 构建产物)
└── h5/ # H5 移动端(UniApp 构建产物)
12.2 构建并推送前端镜像:
docker build -f deployment/docker/frontend/Dockerfile -t vortmall/vortmall-frontend:latest .
docker tag vortmall/vortmall-frontend:latest registry.cn-<地域>.aliyuncs.com/<ACR命名空间>/vortmall-frontend:v1.0.0
docker push registry.cn-<地域>.aliyuncs.com/<ACR命名空间>/vortmall-frontend:v1.0.0
验证:ACR 控制台中 vortmall-frontend 仓库包含 v1.0.0 标签。
步骤 13:修改 K8s ConfigMap
编辑 deployment/k8s/configmap.yaml,将所有连接信息替换为实际值:
apiVersion: v1
kind: ConfigMap
metadata:
name: vortmall-config
namespace: vortmall
data:
# ====== Nacos 注册/配置中心 ======
NACOS_ADDR: "<中间件ECS内网IP>:8848"
NACOS_NAMESPACE: "public"
NACOS_GROUP: "DEFAULT_GROUP"
# ====== MySQL(指向云 RDS) ======
DB_HOST: "<RDS内网地址>"
DB_PORT: "3306"
DB_USERNAME: "<RDS账号>"
DB_PASSWORD: "<RDS密码>"
# ====== Redis(指向云 Redis) ======
REDIS_HOST: "<Redis内网地址>"
REDIS_PORT: "6379"
REDIS_PASSWORD: "<Redis密码>"
# ====== RocketMQ ======
ROCKETMQ_NAMESRV: "<中间件ECS内网IP>:9876"
# ====== Seata ======
SEATA_ADDR: "<中间件ECS内网IP>:8091"
# ====== XXL-Job ======
XXLJOB_ADDR: "http://<中间件ECS内网IP>:8082/xxl-job-admin"
XXLJOB_ACCESS_TOKEN: "<步骤5中设置的新Token>"
# ====== MinIO(如使用 OSS 则此项仅作兜底) ======
MINIO_ENDPOINT: "http://<中间件ECS内网IP>:9000"
MINIO_ACCESS_KEY: "<MinIO新用户名>"
MINIO_SECRET_KEY: "<MinIO新密码>"
# ====== EMQX (MQTT) ======
EMQX_HOST: "<中间件ECS内网IP>"
EMQX_PORT: "1883"
# ====== Elasticsearch(如已部署) ======
ES_HOST: "<中间件ECS内网IP>"
ES_PORT: "9200"
ES_USERNAME: "elastic"
ES_PASSWORD: "<ES新密码>"
# ====== SkyWalking(如已部署) ======
SW_AGENT_COLLECTOR_BACKEND_SERVICES: "<中间件ECS内网IP>:11800"
# ====== Logstash(如已部署) ======
LOGSTASH_HOST: "<中间件ECS内网IP>"
LOGSTASH_PORT: "5001"
# ====== JVM / Spring 公共配置 ======
JAVA_OPTS: "-XX:InitialRAMPercentage=25.0 -XX:MaxRAMPercentage=60.0 -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError"
SPRING_PROFILES_ACTIVE: "default"
TZ: "Asia/Shanghai"
生产环境建议将密码类配置(
DB_PASSWORD、REDIS_PASSWORD、MINIO_SECRET_KEY、ES_PASSWORD、XXLJOB_ACCESS_TOKEN)改为 K8s Secret,避免明文存储。
验证:确认所有 <占位符> 已替换为实际值,无遗漏。
步骤 14:修改镜像地址
将服务 YAML 中的默认镜像地址替换为 ACR 私有仓库地址:
cd deployment/k8s/services
sed -i 's|image: vortmall/|image: registry.cn-<地域>.aliyuncs.com/<ACR命名空间>/|g' *.yaml
同时将镜像标签替换为步骤 11 中使用的版本号:
sed -i 's|:latest|:v1.0.0|g' *.yaml
验证:
grep 'image:' *.yaml
所有行应显示 registry.cn-<地域>.aliyuncs.com/<ACR命名空间>/<服务名>:v1.0.0。
步骤 15:一键 K8s 部署
15.1 确保 kubectl 已配置好 ACK 集群凭证(在 ACK 控制台 → 集群信息 → 连接信息 中获取 kubeconfig)
15.2 在 ACK Worker 节点上配置 ACR 拉取凭证:
kubectl create secret docker-registry acr-secret \
--docker-server=registry.cn-<地域>.aliyuncs.com \
--docker-username=<阿里云账号> \
--docker-password=<ACR密码> \
-n vortmall
15.3 执行部署:
cd deployment/k8s
bash deploy.sh
15.4 等待全部 Pod 就绪:
kubectl wait --for=condition=Ready pods --all -n vortmall --timeout=300s
15.5 查看部署状态:
bash deploy.sh --status
验证:所有 Pod 状态为 Running,READY 列显示 1/1,RESTARTS 为 0。
Pod 异常排查:
| 异常状态 | 常见原因 | 排查命令 | 解决方案 |
|---|---|---|---|
ImagePullBackOff | 镜像地址或 ACR 凭证错误 | kubectl describe pod <Pod名> -n vortmall | 检查镜像地址、ACR Secret |
CrashLoopBackOff | 应用启动失败(连不上中间件) | kubectl logs <Pod名> -n vortmall --tail=100 | 检查 ConfigMap 地址 |
Pending | 节点资源不足 | kubectl describe pod <Pod名> -n vortmall | 增加节点或降低 requests |
OOMKilled | 内存不足 | kubectl describe pod <Pod名> -n vortmall | 调高 resources.limits.memory |
步骤 16:验证全部服务
| 检查项 | 验证方式 | 预期结果 |
|---|---|---|
| K8s Pod | kubectl get pods -n vortmall | 全部 Running,共 18 个 Pod |
| Nacos 服务列表 | 登录 Nacos → 服务管理 → 服务列表 → public 命名空间 | ≥ 17 个已注册 |
| Gateway 健康检查 | curl -s http://<Worker节点IP>:30800/actuator/health | {"status":"UP"} |
| 前端页面 | 浏览器打开 http://<Worker节点IP>:30080 | PC 商城页面正常渲染 |
| 管理后台 | 浏览器打开 http://<Worker节点IP>:30080/admin | 登录页正常显示 |
| H5 移动端 | 浏览器打开 http://<Worker节点IP>:30080/mobile | 页面正常渲染 |
| API 联通 | 浏览器访问管理后台,输入默认管理员账号登录 | 能正常登录 |
| XXL-Job 执行器 | XXL-Job 控制台 → 执行器管理 | 包含已注册的执行器 |
登录管理后台后,立即修改默认管理员密码。
三、域名与 HTTPS
方案一:外部 Nginx(通用)
在一台可公网访问的服务器上安装 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;
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;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
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;
}
}
验证:
nginx -t && systemctl reload nginx
curl -I https://<域名>
预期返回 HTTP/2 200。
方案二:K8s Ingress(ACK 原生)
2.1 创建 TLS Secret:
kubectl create secret tls vortmall-tls \
--cert=<域名>.pem \
--key=<域名>.key \
-n vortmall
2.2 创建 Ingress 资源(保存为 ingress.yaml 并 apply):
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"
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
spec:
ingressClassName: nginx
tls:
- hosts:
- <域名>
secretName: vortmall-tls
rules:
- host: <域名>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vortmall-frontend
port:
number: 80
kubectl apply -f ingress.yaml
验证:
kubectl get ingress -n vortmall
curl -I https://<域名>
路由映射表
前端容器内部已处理全部路由,外层入口(Nginx / Ingress)只需将所有请求转发到 vortmall-frontend 即可:
| URL 路径 | 对应页面 / 服务 |
|---|---|
https://<域名>/ | PC 商城(Nuxt 3) |
https://<域名>/admin | 管理后台(Vue 3) |
https://<域名>/mobile | H5 移动端(UniApp) |
https://<域名>/api/* | 前台 API → Gateway |
https://<域名>/adminapi/* | 后台 API → Gateway |
四、全链路验证
部署完成后,按以下清单逐项确认全链路通畅:
# 1. 检查所有 Pod 状态
kubectl get pods -n vortmall -o wide
# 2. 检查所有 Service
kubectl get svc -n vortmall
# 3. 检查 Nacos 注册服务数(预期 ≥ 17)
curl -s "http://<中间件IP>:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=50&namespaceId=public" | python3 -m json.tool
# 4. 检查 Gateway 健康
curl -s http://<Worker节点IP>:30800/actuator/health
# 5. 检查前端页面
curl -s -o /dev/null -w "%{http_code}" http://<Worker节点IP>:30080
curl -s -o /dev/null -w "%{http_code}" http://<Worker节点IP>:30080/admin
curl -s -o /dev/null -w "%{http_code}" http://<Worker节点IP>:30080/mobile
# 6. 检查 HTTPS(域名已配置后)
curl -s -o /dev/null -w "%{http_code}" https://<域名>
curl -s -o /dev/null -w "%{http_code}" https://<域名>/admin
# 7. 检查 API 通路
curl -s https://<域名>/api/actuator/health
# 8. 检查数据库连接(从任意 Pod 内部)
kubectl exec -it $(kubectl get pod -n vortmall -l app=vortmall-biz-system -o jsonpath='{.items[0].metadata.name}') -n vortmall -- sh -c 'curl -s localhost:19903/actuator/health'
# 9. 检查 XXL-Job 执行器注册
curl -s "http://<中间件IP>:8082/xxl-job-admin/jobgroup/pageList" -d "appname=&start=0&length=20"
以上每一项的预期输出:
| 序号 | 预期 |
|---|---|
| 1 | 18 个 Pod 全部 Running |
| 2 | 18 个 Service 正常 |
| 3 | count ≥ 17 |
| 4 | {"status":"UP"} |
| 5~6 | HTTP 状态码 200 |
| 7 | {"status":"UP"} |
| 8 | {"status":"UP"} |
| 9 | 包含已注册的执行器列表 |
五、安全加固
5.1 密码最终核查表
部署完成后,对照以下清单确认所有默认密码已修改:
- RDS MySQL — 步骤 1 中已使用自定义强密码创建账号
- 云 Redis — 步骤 2 中已设置自定义强密码
- OSS RAM 子账号 — 步骤 3 中已创建独立 AK/SK
- Nacos — 已从
nacos/nacos修改为新密码 - XXL-Job Admin — 已从
admin/123456修改为新密码 - XXL-Job accessToken — 已从
default_token修改为新 Token - MinIO — 已从
vortmall/vortmall666修改为新账号密码 - EMQX — 已从
admin/vortmall666修改为新密码 - Elasticsearch — 已从
elastic/vortmall666修改为新密码 - Canal — 已从
canal/canal123修改为新密码 - 商城管理后台 — 已修改默认管理员密码
- ACR 镜像仓库 — 已设置独立访问凭证
- K8s ConfigMap — 所有密码项已同步为修改后的值
5.2 安全组规则
公网入方向(仅开放必要端口):
| 端口 | 协议 | 来源 | 说明 |
|---|---|---|---|
| 80 | TCP | 0.0.0.0/0 | HTTP(自动跳转 HTTPS) |
| 443 | TCP | 0.0.0.0/0 | HTTPS |
| 22 | TCP | 办公 IP 段 | SSH(严格限定来源) |
内网入方向:
| 端口 | 协议 | 来源 | 说明 |
|---|---|---|---|
| 全部 | TCP | VPC 网段(如 10.0.0.0/8) | 内网服务互通 |
严禁将中间件端口(8848、9876、8082、3306、6379、9200 等)对公网开放。
5.3 Nginx 安全加固
如使用方案一(外部 Nginx),追加以下配置:
# 隐藏版本号
server_tokens off;
# API 限速(防 CC 攻击)
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(防止 IP 直接访问)
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;
}
六、日常运维
6.1 K8s 操作速查
| 操作 | 命令 |
|---|---|
| 查看所有 Pod | kubectl get pods -n vortmall -o wide |
| 查看日志(实时) | 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=2 -n vortmall |
| 缩容 | kubectl scale deploy/vortmall-biz-order --replicas=1 -n vortmall |
| 查看资源占用 | kubectl top pods -n vortmall |
| 进入容器 | kubectl exec -it <Pod名> -n vortmall -- sh |
| 查看事件 | kubectl get events -n vortmall --sort-by='.lastTimestamp' |
6.2 版本升级(滚动更新)
# 1. 备份数据库(RDS 控制台手动触发备份,或使用 mysqldump)
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 --default-character-set=utf8mb4 < db/update/update-v1.1.0.sql
# 3. 构建新版本镜像并推送
cd deployment/k8s
REGISTRY=registry.cn-<地域>.aliyuncs.com/<ACR命名空间> TAG=v1.1.0 bash build.sh --push
# 4. 滚动更新指定服务
kubectl set image deployment/vortmall-biz-order \
vortmall-biz-order=registry.cn-<地域>.aliyuncs.com/<ACR命名空间>/vortmall-biz-order:v1.1.0 \
-n vortmall
# 5. 监控更新进度
kubectl rollout status deployment/vortmall-biz-order -n vortmall
# 6. 批量更新全部服务(如需)
cd deployment/k8s/services
sed -i 's|:v1.0.0|:v1.1.0|g' *.yaml
cd ..
bash deploy.sh
6.3 回滚
# K8s 回滚到上一版本
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_20260328.sql.gz | mysql -h <RDS内网地址> -u vortmall -p
6.4 RDS 自动备份
- 登录 RDS 控制台 → 备份恢复
- 开启自动备份:每天凌晨 2:00~3:00,保留 7 天
- 开启 Binlog 备份(增量恢复)
- 建议额外配置跨地域备份(灾备场景)
6.5 磁盘清理
# 清理 7 天前的无用 Docker 镜像
docker image prune -a --filter "until=168h" -f
# 清理构建缓存
docker builder prune -f
# 清理中间件日志(中间件 ECS 上执行)
find /opt/vortmall -name "*.log" -mtime +7 -delete
# 查看磁盘使用
df -h
docker system df
七、常见问题
7.1 Pod CrashLoopBackOff
Java 应用启动失败,通常是连不上中间件。
kubectl logs <Pod名> -n vortmall --tail=100
| 日志关键词 | 原因 | 解决 |
|---|---|---|
Connection refused | 中间件未启动或地址错误 | 检查 ConfigMap 中的地址,确认中间件 ECS 上容器状态 |
Access denied | 数据库账号密码错误 | 检查 ConfigMap 中的 DB_USERNAME / DB_PASSWORD |
No DataSource | 数据库未初始化 | 确认 SQL 已导入(步骤 7) |
Nacos connected failed | Nacos 地址或命名空间不匹配 | 检查 NACOS_ADDR 和 NACOS_NAMESPACE |
OutOfMemoryError | 内存 limit 太低 | 调高 JAVA_OPTS 中的 MaxRAMPercentage 或服务 YAML 中的 resources.limits.memory |
7.2 ImagePullBackOff
kubectl describe pod <Pod名> -n vortmall | grep -A5 Events
| 原因 | 解决 |
|---|---|
| 镜像不存在 | 确认步骤 11/12 推送成功,ACR 仓库中有对应标签 |
| 认证失败 | 检查 acr-secret 是否创建正确,服务 YAML 是否配置了 imagePullSecrets |
| 网络不通 | 确认 Worker 节点可访问 registry.cn-<地域>.aliyuncs.com |
7.3 前端页面空白
# 检查前端 Pod 是否正常
kubectl logs deploy/vortmall-frontend -n vortmall --tail=50
# 进入容器检查文件
kubectl exec -it $(kubectl get pod -n vortmall -l app=vortmall-frontend -o jsonpath='{.items[0].metadata.name}') -n vortmall -- ls -la /usr/share/nginx/html/
# 检查 API 代理
kubectl exec -it $(kubectl get pod -n vortmall -l app=vortmall-frontend -o jsonpath='{.items[0].metadata.name}') -n vortmall -- curl -s http://vortmall-gateway:8000/actuator/health
| 原因 | 解决 |
|---|---|
| 前端构建产物为空 | 确认步骤 12 中 public/ 目录包含 pc/、admin/、h5/ |
| API 代理失败 | 确认 Gateway Pod 正常运行 |
| JS/CSS 加载 404 | 检查 Nginx 配置和构建产物路径 |
7.4 Nacos 服务列表为空
# 确认命名空间 ID 一致
curl -s 'http://<中间件IP>:8848/nacos/v1/console/namespaces'
# 从 Worker 节点测试 Nacos 连通性
kubectl exec -it <任意Pod> -n vortmall -- sh -c 'nc -zv <中间件IP> 8848 && nc -zv <中间件IP> 9848'
| 原因 | 解决 |
|---|---|
| 命名空间 ID 不匹配 | ConfigMap 中 NACOS_NAMESPACE 必须填 public(不是名称 VortMall) |
| 网络不通 | 检查安全组是否放通 Worker → 中间件 ECS 的 8848 和 9848 端口 |
| gRPC 端口未开放 | Nacos 2.x 需要同时开放 9848(gRPC)端口 |
7.5 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 调高 |
| 排查连接泄露 | 检查 SHOW PROCESSLIST 中是否有大量 Sleep 状态连接 |
| 优化连接池 | 调整 Nacos 中 datasource-multiple.yml 的连接池大小 |
附录
附录 A:端口速查表
中间件端口
| 服务 | 端口 | 说明 |
|---|---|---|
| Nacos | 8848, 9848 | 配置中心 + 服务发现(HTTP + gRPC) |
| RocketMQ NameServer | 9876 | MQ 名称服务 |
| RocketMQ Broker | 10909, 10911, 10912 | MQ Broker |
| RocketMQ Dashboard | 8080 | MQ 管理界面 |
| XXL-Job Admin | 8082 | 任务调度管控台 |
| Seata | 7091, 8091 | 分布式事务(控制台 + 服务) |
| MinIO | 9000 (API), 9001 (Console) | 对象存储 |
| EMQX | 1883 (MQTT), 8083 (WS), 18083 (Dashboard) | 消息总线 |
| Elasticsearch | 9200, 9300 | 搜索引擎 |
| Kibana | 5601 | ES 可视化 |
| Logstash | 5001, 5044 | 日志收集 |
| Canal | 11111, 11112 | 数据同步 |
| SkyWalking OAP | 11800, 12800 | 链路追踪(gRPC + HTTP) |
| SkyWalking UI | 18080 | 链路追踪界面 |
应用服务端口
| 服务 | HTTP 端口 | XXL-Job 端口 | K8s NodePort |
|---|---|---|---|
| vortmall-frontend | 80 | — | 30080 |
| vortmall-gateway | 8000 | — | 30800 |
| vortmall-auth | 8001 | — | — |
| vortmall-biz-product | 19901 | — | — |
| vortmall-biz-payment | 19902 | 19702 | — |
| vortmall-biz-system | 19903 | — | — |
| vortmall-biz-marketing | 19904 | — | — |
| vortmall-biz-order | 19905 | 19705 | — |
| vortmall-biz-content | 19906 | — | — |
| vortmall-biz-organize | 19907 | — | — |
| vortmall-biz-logistics | 19908 | — | — |
| vortmall-biz-aftersales | 19909 | — | — |
| vortmall-biz-distribution | 19910 | — | — |
| vortmall-biz-decoration | 19911 | — | — |
| vortmall-biz-message | 19912 | — | — |
| vortmall-biz-user | 19913 | — | — |
| vortmall-biz-file | 19914 | — | — |
| vortmall-biz-pos | 19915 | — | — |
附录 B:服务列表
| 序号 | 服务名 | 注册名 | 数据库 | 说明 |
|---|---|---|---|---|
| 1 | Gateway | vortmall-gateway | — | API 网关、路由、鉴权分发 |
| 2 | Auth | vortmall-auth | — | 认证授权(JWT 签发) |
| 3 | Product | vortmall-biz-product | vortmall_product | 商品、分类、品牌、规格 |
| 4 | Payment | vortmall-biz-payment | vortmall_payment | 支付、退款 |
| 5 | System | vortmall-biz-system | vortmall_system | 系统配置、菜单、权限、管理员 |
| 6 | Marketing | vortmall-biz-marketing | vortmall_marketing | 营销活动、优惠券、满减 |
| 7 | Order | vortmall-biz-order | vortmall_order | 订单、购物车、结算 |
| 8 | Content | vortmall-biz-content | vortmall_content | 文章、公告 |
| 9 | Organize | vortmall-biz-organize | vortmall_organize | 组织架构、店铺管理 |
| 10 | Logistics | vortmall-biz-logistics | vortmall_logistics | 物流、运费模板 |
| 11 | Aftersales | vortmall-biz-aftersales | vortmall_aftersales | 售后、退货退款 |
| 12 | Distribution | vortmall-biz-distribution | vortmall_distribution | 分销 |
| 13 | Decoration | vortmall-biz-decoration | vortmall_decoration | 页面装修 |
| 14 | Message | vortmall-biz-message | vortmall_message | 消息、通知、短信 |
| 15 | User | vortmall-biz-user | vortmall_user | 用户、会员 |
| 16 | File | vortmall-biz-file | vortmall_file | 文件上传 |
| 17 | POS | vortmall-biz-pos | vortmall_pos | 收银台、门店、O2O |
赣公网安备36010902001041号