VortMall 入门版部署指南
VortMall 入门版部署指南
文档说明
适用场景:DAU < 1,000 的正式生产环境,适合初创团队、中小商户首次上线。
架构概览:采用 2 台阿里云 ECS 分离部署——1 台中间件服务器(8C16G)承载 MySQL、Redis、Nacos 等全套中间件(Docker Compose 自建),1 台应用服务器(4C16G)运行 K8s(k3s 单节点)部署 17 个微服务和前端。中间件与应用通过 VPC 内网通信,公网仅暴露 80/443 端口。后续业务增长可平滑升级到标准版(ACK 托管 + 云 RDS/Redis)或企业版(多节点 + 高可用),无需重建。
约定:
<尖括号>表示需替换为实际值的占位符- 命令示例中
#开头的行为注释,不需要执行 - 所有服务器使用 Linux(CentOS 7+ / Ubuntu 20+ / Alibaba Cloud Linux 3)
[!CAUTION]
正式上线前必须修改全部默认密码,否则存在严重安全风险!本部署包中所有中间件均使用公开的默认密码(MySQL:
vortmall666、Redis:vortmall666、MinIO:vortmall/vortmall666、EMQX:admin/vortmall666、Elasticsearch:elastic/vortmall666、XXL-Job:admin/123456、XXL-Job accessToken:default_token、Nacos:nacos/nacos、Canal:canal/canal123),若不修改直接上线,任何人均可通过默认凭据入侵系统。请在 步骤 4 中逐项完成密码修改,并在 第五章安全加固 中最终核查。
一、采购清单
服务器
| 产品 | 规格 | 数量 | 用途 |
|---|---|---|---|
| ECS(应用服务器) | 4C16G ecs.g7.xlarge,系统盘 40G + 数据盘 50G ESSD | 1 台 | K8s(k3s)+ 17 个微服务 + 前端 |
| ECS(中间件服务器) | 8C16G ecs.g7.2xlarge,系统盘 40G + 数据盘 200G ESSD | 1 台 | MySQL、Redis、Nacos 等全套中间件 |
| EIP | 按流量计费 | 1 个 | 公网访问入口 |
两台 ECS 须在同一 VPC、同一可用区,内网互通。
购买链接
| 产品 | 控制台地址 |
|---|---|
| ECS | https://ecs-buy.aliyun.com/ |
| 域名注册 | https://wanwang.aliyun.com/domain |
| SSL 证书 | https://yundun.console.aliyun.com/?p=cas |
| CDN(按需) | https://cdn.console.aliyun.com/ |
公共配套
- 域名:至少 1 个(
.com/.cn),需完成 ICP 备案(周期 7~20 个工作日),建议采购服务器时同步提交备案 - SSL 证书:入门版用免费单域名证书即可(阿里云每年 20 张免费额度)
- CDN(按需):商品图片多、全国访问要求高时开通
需要提前准备的信息
| 信息 | 说明 | 示例 |
|---|---|---|
| 中间件服务器内网 IP | Docker Compose 中间件通信地址 | 10.0.0.11 |
| 应用服务器内网 IP | K8s 节点地址 | 10.0.0.12 |
| 公网 IP(EIP) | 绑定到应用服务器或外部 Nginx | 47.100.xxx.xxx |
| 域名 | 已备案、已做 DNS A 记录解析 | mall.example.com |
| SSL 证书文件 | .pem + .key 格式 | — |
| 强密码清单 | 为以下每个组件各准备一个强密码(至少 16 位,含大小写字母+数字+特殊字符) | — |
强密码清单(请在部署前确定并妥善保管):
| 组件 | 用途 | 您的新密码 |
|---|---|---|
| MySQL root | 数据库超级管理员 | ______________ |
| Redis | 缓存访问密码 | ______________ |
| MinIO | 对象存储管理员 | ______________ |
| EMQX | MQTT 消息 Dashboard | ______________ |
| Elasticsearch | 搜索引擎 | ______________ |
| XXL-Job admin | 任务调度管理台 | ______________ |
| XXL-Job accessToken | 执行器通信令牌 | ______________ |
| Nacos | 配置/注册中心 | ______________ |
| Canal | 数据同步 MySQL 账号 | ______________ |
| 商城管理后台超管 | 系统管理员登录 | ______________ |
二、部署步骤
步骤 1:安装 Docker(两台服务器都执行)
分别 SSH 登录两台服务器,执行以下命令:
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+。
步骤 2:应用服务器安装 K8s(仅应用服务器执行)
推荐使用 k3s(轻量 K8s 发行版),单节点即可满足入门版需求,后续升级到标准版/企业版时可平滑迁移到 ACK 托管集群。
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
k3s 自带 containerd 运行时,与步骤 1 安装的 Docker 互不冲突。构建镜像用 Docker,运行 Pod 用 k3s 内置的 containerd。
验证:
kubectl get nodes
预期输出:节点状态为 Ready。
NAME STATUS ROLES AGE VERSION
<应用服务器> Ready control-plane,master 1m v1.28+k3s1
步骤 3:上传部署文件到中间件服务器
在开发机(有源码的机器)上执行:
scp -r deployment/DockerCompose/ root@<中间件服务器IP>:/opt/vortmall/
确保
/opt/vortmall/DockerCompose/目录包含docker-compose.yml、start-core.sh及各中间件配置目录。
步骤 4:修改默认密码(启动中间件前必做!!!)
[!CAUTION]
此步骤必须在启动中间件之前完成。 中间件首次启动时会用配置文件中的密码初始化数据。启动后再改密码需要额外的迁移操作,更加麻烦。
SSH 登录中间件服务器:
ssh root@<中间件服务器IP>
cd /opt/vortmall/DockerCompose
以下是所有需要修改的密码清单及对应操作:
| 组件 | 默认账号/密码 | 配置文件中的修改位置 | 修改后需同步更新 |
|---|---|---|---|
| MySQL root | root / vortmall666 | docker-compose.yml → MYSQL_ROOT_PASSWORD | Nacos 的 datasource-multiple.yml、K8s configmap.yaml |
| Redis | vortmall666 | redis/config/redis.conf → requirepass | K8s configmap.yaml |
| MinIO | vortmall / vortmall666 | docker-compose.yml → MINIO_ROOT_USER / MINIO_ROOT_PASSWORD | K8s configmap.yaml |
| EMQX | admin / vortmall666 | docker-compose.yml → EMQX_DASHBOARD__DEFAULT_PASSWORD | — |
| Elasticsearch | elastic / vortmall666 | docker-compose.yml → ELASTIC_PASSWORD | K8s configmap.yaml |
| XXL-Job 数据库连接 | vortmall / vortmall666 | xxl-job/config/application.properties → spring.datasource.password | — |
| XXL-Job admin | admin / 123456 | 启动后登录管理台修改 | — |
| XXL-Job accessToken | default_token | xxl-job/config/application.properties → xxl.job.accessToken | K8s configmap.yaml 或应用 Nacos 配置 |
| Nacos | nacos / nacos | 启动后登录控制台修改 | — |
| Canal | canal / canal123 | start-core.sh 自动创建,可在 MySQL 中修改密码 | Canal 配置文件 canal/conf/instance.properties |
4.1 修改 docker-compose.yml
编辑 docker-compose.yml,找到并替换以下环境变量值:
vi docker-compose.yml
需要修改的位置(搜索并替换):
| 搜索内容 | 替换为 |
|---|---|
MYSQL_ROOT_PASSWORD=vortmall666 | MYSQL_ROOT_PASSWORD=<MySQL新密码> |
MINIO_ROOT_USER=vortmall | MINIO_ROOT_USER=<MinIO新用户名> |
MINIO_ROOT_PASSWORD=vortmall666 | MINIO_ROOT_PASSWORD=<MinIO新密码> |
EMQX_DASHBOARD__DEFAULT_PASSWORD=vortmall666 | EMQX_DASHBOARD__DEFAULT_PASSWORD=<EMQX新密码> |
ELASTIC_PASSWORD=vortmall666 | ELASTIC_PASSWORD=<ES新密码> |
同时修改 Kibana 和 SkyWalking 中引用的 ES 密码:
- Kibana 的
ELASTICSEARCH_PASSWORD=vortmall666→<ES新密码> - SkyWalking OAP 的
SW_ES_PASSWORD=vortmall666→<ES新密码> - ES healthcheck 中的
curl -u elastic:vortmall666→curl -u elastic:<ES新密码>
4.2 修改 Redis 密码
vi redis/config/redis.conf
找到 requirepass vortmall666,修改为:
requirepass <Redis新密码>
4.3 修改 XXL-Job 配置
vi xxl-job/config/application.properties
修改以下两项:
spring.datasource.password=<MySQL新密码>
xxl.job.accessToken=<新accessToken>
XXL-Job 使用名为
vortmall的 MySQL 用户连接数据库。如果 MySQL root 密码改了,也需要同步修改此处的连接密码,或在 MySQL 中为vortmall用户单独设置密码。
4.4 修改 Canal 数据库连接密码(如需)
如果修改了 Canal MySQL 用户的密码,需要同步更新:
vi canal/conf/instance.properties
找到 canal.instance.dbPassword=canal123,修改为新密码。
验证:确认所有配置文件已保存,检查关键密码是否都已替换:
grep -n "vortmall666" docker-compose.yml
grep -n "vortmall666" redis/config/redis.conf
grep -n "default_token" xxl-job/config/application.properties
预期:以上命令均无输出(所有默认密码已被替换)。
步骤 5:启动中间件
在中间件服务器上执行:
cd /opt/vortmall/DockerCompose
bash start-core.sh
脚本会提示输入服务器 IP 地址,填写中间件服务器的内网 IP。脚本将依次:
- 替换配置文件中的 IP 占位符
- 启动 MySQL、Redis
- 等待 MySQL 健康后初始化 Canal 账号
- 启动 Nacos 及其余中间件
首次启动需要拉取镜像,视网络情况约需 5~15 分钟。
验证(等待约 2~3 分钟后逐项检查):
| 服务 | 验证命令 | 预期结果 |
|---|---|---|
| 容器状态 | docker compose ps | 所有容器 Up |
| MySQL | docker exec mysql-8 mysqladmin ping -uroot -p<新密码> | mysqld is alive |
| Redis | docker exec redis redis-cli -a <新密码> ping | PONG |
| Nacos | 浏览器打开 http://<中间件IP>:8848/nacos,用 nacos/nacos 登录 | 能登录控制台 |
| RocketMQ | 浏览器打开 http://<中间件IP>:8080 | Dashboard 页面正常 |
| XXL-Job | 浏览器打开 http://<中间件IP>:8082/xxl-job-admin,用 admin/123456 登录 | 能登录 |
| MinIO | 浏览器打开 http://<中间件IP>:9001,用 <MinIO新用户>/<MinIO新密码> 登录 | 能登录控制台 |
| EMQX | 浏览器打开 http://<中间件IP>:18083,用 admin/<EMQX新密码> 登录 | 能登录 Dashboard |
| Elasticsearch | curl -u elastic:<ES新密码> http://<中间件IP>:9200/_cluster/health | 返回 green 或 yellow |
全部验证通过后再进入下一步。如果某项失败,执行
docker compose logs <服务名>检查日志。
步骤 6:初始化数据库
在中间件服务器上执行(将 SQL 文件上传到中间件服务器后):
# 上传 SQL 文件(在开发机执行)
scp db/version/mysql/pure.sql root@<中间件服务器IP>:/opt/vortmall/
# 在中间件服务器上导入
docker exec -i mysql-8 mysql -uroot -p<MySQL新密码> < /opt/vortmall/pure.sql
正式生产环境使用
pure.sql(空库,无演示数据)。如需体验可改用demo.sql。
验证(应有 15 个 vortmall_* 数据库):
docker exec mysql-8 mysql -uroot -p<MySQL新密码> -e "
SELECT TABLE_SCHEMA, COUNT(*) AS '表数量'
FROM information_schema.TABLES
WHERE TABLE_SCHEMA LIKE 'vortmall_%'
GROUP BY TABLE_SCHEMA;
"
预期输出:15 个 vortmall_ 开头的数据库,每个库包含若干表。
步骤 7:修改商城管理后台默认密码
SQL 导入后会创建默认超级管理员账号。部署完成后请第一时间登录管理后台修改管理员密码。
管理后台默认地址:
https://<域名>/admin(域名配置完成后)或http://<应用服务器IP>:30080/admin(K8s 部署完成后临时访问)
步骤 8:配置 Nacos
-
浏览器打开
http://<中间件IP>:8848/nacos,用nacos/nacos登录 -
修改 Nacos 登录密码:登录后在控制台修改
nacos用户的密码 -
左侧菜单 → 命名空间 → 新建命名空间:
- 命名空间 ID:
public - 命名空间名:
VortMall
- 命名空间 ID:
-
切换到
public命名空间 → 配置管理 → 配置列表 → 创建配置:- Data ID:
datasource-multiple.yml - Group:
DEFAULT_GROUP - 格式:YAML
- 内容如下(将
<中间件内网IP>和<MySQL新密码>替换为实际值):
- Data ID:
spring:
datasource:
dynamic:
primary: master
strict: true
datasource:
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://<中间件内网IP>:3306/${vortmall.datasource.db-name}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
username: root
password: <MySQL新密码>
${vortmall.datasource.db-name}是 Spring 变量占位符,每个微服务会自动填入自己的库名,不需要替换。只需替换<中间件内网IP>和<MySQL新密码>。
验证:在配置列表中能看到刚创建的 datasource-multiple.yml,点击查看内容无误。
步骤 9:XXL-Job 配置确认
-
浏览器打开
http://<中间件IP>:8082/xxl-job-admin,用admin/123456登录 -
立即修改 admin 密码:右上角 → 修改密码 → 设置为步骤 4 中准备的新密码
-
确认执行器管理页面已准备好接收自动注册的执行器
应用服务启动后,执行器会自动注册到 XXL-Job(名称格式为
{服务名}-executor,如vortmall-biz-order-executor)。
重要:如果步骤 4 中修改了
xxl.job.accessToken,需确保应用服务的配置中使用了相同的 token 值(在步骤 12 的 ConfigMap 或 Nacos 配置中设置)。
步骤 10:构建后端镜像
在开发机上执行,需要 JDK 21+ 和 Maven 3.9+。
cd deployment/k8s
bash build.sh
首次构建需要下载 Maven 依赖和构建 17 个 Docker 镜像,约需 10~15 分钟。
验证:
docker images | grep vortmall
预期输出:应有 17 个 vortmall/ 前缀的镜像(gateway、auth、15 个 biz 服务)。
构建完成后,将镜像传输到应用服务器:
# 方式一:导出为 tar 文件后 scp 传输
docker save $(docker images --format '{{.Repository}}:{{.Tag}}' | grep vortmall/) | gzip > vortmall-images.tar.gz
scp vortmall-images.tar.gz root@<应用服务器IP>:/opt/vortmall/
# 在应用服务器上导入到 k3s
ssh root@<应用服务器IP>
gunzip -c /opt/vortmall/vortmall-images.tar.gz | k3s ctr images import -
步骤 11:构建前端镜像
前端共三个项目(管理后台、PC 商城、H5 移动端),需分别构建后将产物放入指定目录:
# 在项目根目录下创建前端产物目录
mkdir -p public/admin public/h5 public/pc
# 将各前端项目的构建产物(dist)复制到对应目录:
# - Vort-Admin 的 dist/ → public/admin/
# - Vortmall-Pc 的 .output/public/ → public/pc/
# - vortmall-uniapp 的 dist/build/h5/ → public/h5/
构建前端镜像:
docker build -f deployment/docker/frontend/Dockerfile -t vortmall/vortmall-frontend:latest .
将前端镜像也传输到应用服务器:
docker save vortmall/vortmall-frontend:latest | gzip > vortmall-frontend.tar.gz
scp vortmall-frontend.tar.gz root@<应用服务器IP>:/opt/vortmall/
# 在应用服务器上导入
ssh root@<应用服务器IP>
gunzip -c /opt/vortmall/vortmall-frontend.tar.gz | k3s ctr images import -
验证(在应用服务器上):
k3s crictl images | grep vortmall
预期输出:18 个镜像(17 个后端 + 1 个前端)。
步骤 12:修改 ConfigMap
在开发机上编辑 deployment/k8s/configmap.yaml,将所有地址和密码改为实际值:
apiVersion: v1
kind: ConfigMap
metadata:
name: vortmall-config
namespace: vortmall
data:
# ====== Nacos 注册/配置中心 ======
NACOS_ADDR: "<中间件内网IP>:8848" # Nacos 地址
NACOS_NAMESPACE: "public" # 命名空间 ID(步骤 8 中创建的)
NACOS_GROUP: "DEFAULT_GROUP" # 配置分组
# ====== MySQL ======
DB_HOST: "<中间件内网IP>" # MySQL 地址
DB_PORT: "3306" # MySQL 端口
DB_USERNAME: "root" # MySQL 用户名
DB_PASSWORD: "<MySQL新密码>" # 步骤 4 中设定的新密码
# ====== Redis ======
REDIS_HOST: "<中间件内网IP>" # Redis 地址
REDIS_PORT: "6379" # Redis 端口
REDIS_PASSWORD: "<Redis新密码>" # 步骤 4 中设定的新密码
# ====== RocketMQ ======
ROCKETMQ_NAMESRV: "<中间件内网IP>:9876" # RocketMQ NameServer 地址
# ====== Seata ======
SEATA_ADDR: "<中间件内网IP>:8091" # Seata 分布式事务地址
# ====== XXL-Job ======
XXLJOB_ADDR: "http://<中间件内网IP>:8082/xxl-job-admin" # XXL-Job 管理台地址
# ====== MinIO ======
MINIO_ENDPOINT: "http://<中间件内网IP>:9000" # MinIO API 地址
MINIO_ACCESS_KEY: "<MinIO新用户名>" # 步骤 4 中设定的新用户名
MINIO_SECRET_KEY: "<MinIO新密码>" # 步骤 4 中设定的新密码
# ====== EMQX (MQTT) ======
EMQX_HOST: "<中间件内网IP>" # EMQX 地址
EMQX_PORT: "1883" # MQTT TCP 端口
# ====== Elasticsearch ======
ES_HOST: "<中间件内网IP>" # Elasticsearch 地址
ES_PORT: "9200" # Elasticsearch HTTP 端口
ES_USERNAME: "elastic" # ES 用户名
ES_PASSWORD: "<ES新密码>" # 步骤 4 中设定的新密码
# ====== SkyWalking ======
SW_AGENT_COLLECTOR_BACKEND_SERVICES: "<中间件内网IP>:11800" # SkyWalking Agent 上报地址
# ====== Logstash ======
LOGSTASH_HOST: "<中间件内网IP>" # Logstash 地址
LOGSTASH_PORT: "5001" # Logstash HTTP 输入端口
# ====== JVM / Spring 公共配置 ======
JAVA_OPTS: "-XX:InitialRAMPercentage=25.0 -XX:MaxRAMPercentage=60.0 -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError"
SPRING_PROFILES_ACTIVE: "default"
TZ: "Asia/Shanghai"
所有
<中间件内网IP>替换为同一个值——中间件服务器的 VPC 内网 IP。所有密码使用步骤 4 中设定的新密码。
将修改后的 K8s 部署文件上传到应用服务器:
scp -r deployment/k8s/ root@<应用服务器IP>:/opt/vortmall/k8s/
步骤 13:K8s 一键部署
SSH 登录应用服务器:
ssh root@<应用服务器IP>
cd /opt/vortmall/k8s
bash deploy.sh
脚本会依次创建 vortmall 命名空间、应用 ConfigMap、部署所有服务,并等待 Pod 就绪。
如果部分 Pod 未在 5 分钟内就绪,可手动查看状态:
kubectl get pods -n vortmall -o wide
验证:
# 所有 Pod 状态为 Running,RESTARTS 为 0
kubectl get pods -n vortmall
# 查看部署状态摘要
bash deploy.sh --status
Pod 异常排查:
| 状态 | 常见原因 | 解决方法 |
|---|---|---|
ImagePullBackOff | 镜像不存在或未导入 | k3s crictl images | grep <服务名> 检查镜像是否存在 |
CrashLoopBackOff | 应用启动失败,通常是连不上中间件 | kubectl logs <pod名> -n vortmall --tail=100 查日志,检查 ConfigMap 地址和密码 |
Pending | 节点资源不足 | kubectl describe pod <pod名> -n vortmall 查看事件,检查 CPU/内存 |
OOMKilled | 内存不足 | 调高服务 YAML 中 resources.limits.memory |
排查命令:
# 查看 Pod 详情和事件
kubectl describe pod <pod名称> -n vortmall
# 查看 Pod 日志
kubectl logs <pod名称> -n vortmall --tail=200
步骤 14:验证全部服务
应用服务
# 所有 Pod 为 Running,RESTARTS 为 0
kubectl get pods -n vortmall
Nacos 服务注册
浏览器打开 http://<中间件IP>:8848/nacos → 服务管理 → 服务列表 → 切换到 public 命名空间。
预期:已注册服务数 ≥ 17。
前端页面
浏览器打开 http://<应用服务器IP>:30080,预期页面正常渲染。
API 健康检查
curl http://<应用服务器IP>:30800/actuator/health
预期输出:{"status":"UP"}
XXL-Job 执行器
登录 XXL-Job 管理台 → 执行器管理,预期看到已自动注册的执行器。
三、域名与 HTTPS
在应用服务器或另一台 ECS 上安装 Nginx,配置域名和 SSL。
安装 Nginx
# Ubuntu / Debian
apt update && apt install -y nginx
# CentOS / Alibaba Cloud Linux
yum install -y nginx
Nginx 完整配置
将以下内容写入 /etc/nginx/conf.d/vortmall.conf:
upstream vortmall_frontend {
server <应用服务器内网IP>:30080;
keepalive 64;
}
upstream vortmall_gateway {
server <应用服务器内网IP>:30800;
keepalive 64;
}
# HTTP 强制跳转 HTTPS
server {
listen 80;
server_name <域名>;
return 301 https://$host$request_uri;
}
# HTTPS 主站
server {
listen 443 ssl http2;
server_name <域名>;
# SSL 证书
ssl_certificate /etc/nginx/ssl/<域名>.pem;
ssl_certificate_key /etc/nginx/ssl/<域名>.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
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 ~* \.(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;
}
# WebSocket 支持
location /ws {
proxy_pass http://vortmall_frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 3600s;
}
# 默认代理到前端
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 "";
}
}
# 拦截非预期 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;
}
上传证书并启动
mkdir -p /etc/nginx/ssl
cp <域名>.pem <域名>.key /etc/nginx/ssl/
# 验证配置语法
nginx -t
# 启动 Nginx
systemctl start nginx && systemctl enable nginx
路由映射表
前端容器内部已处理所有路由分发,外层 Nginx 只需统一代理到前端 Service:
| URL 路径 | 对应页面/服务 |
|---|---|
https://<域名>/ | PC 商城(Nuxt 3) |
https://<域名>/admin | 管理后台(Vue 3) |
https://<域名>/mobile | H5 移动端(UniApp) |
https://<域名>/api/* | 前台 API → Gateway |
https://<域名>/adminapi/* | 后台 API → Gateway |
验证:
# HTTP 自动跳转 HTTPS
curl -I http://<域名>
# 预期:HTTP/1.1 301 Moved Permanently, Location: https://...
# HTTPS 页面可访问
curl -I https://<域名>
# 预期:HTTP/2 200
四、全链路验证
部署完成后,按以下清单逐项验证:
中间件连通性
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| MySQL | docker exec mysql-8 mysqladmin ping -uroot -p<新密码> | mysqld is alive |
| Redis | docker exec redis redis-cli -a <新密码> ping | PONG |
| Nacos 控制台 | 浏览器 http://<中间件IP>:8848/nacos | 能登录 |
| RocketMQ | curl -s http://<中间件IP>:8080/cluster/list.query | 包含 broker 信息 |
| MinIO | curl -s http://<中间件IP>:9000/minio/health/live | HTTP 200 |
| Elasticsearch | curl -u elastic:<新密码> http://<中间件IP>:9200/_cluster/health | green 或 yellow |
| EMQX | 浏览器 http://<中间件IP>:18083 | 能登录 |
服务健康
# 所有 Pod Running,RESTARTS 为 0
kubectl get pods -n vortmall
# Nacos 服务列表 ≥ 17
# 浏览器打开 Nacos → 服务列表(public 命名空间)
前端页面
| 页面 | 地址 | 预期 |
|---|---|---|
| PC 商城 | https://<域名>/ | 页面正常渲染 |
| 管理后台 | https://<域名>/admin | 登录页正常显示 |
| H5 移动端 | https://<域名>/mobile | 页面正常渲染 |
API 接口
curl -s https://<域名>/api/actuator/health
# 预期:{"status":"UP"}
五、安全加固
密码最终核查表
正式上线前,逐项确认所有默认密码已修改:
- MySQL root 密码已从
vortmall666修改为强密码 - Redis 密码已从
vortmall666修改为强密码 - MinIO 用户名/密码已从
vortmall/vortmall666修改为强密码 - EMQX Dashboard 密码已从
vortmall666修改为强密码 - Elasticsearch 密码已从
vortmall666修改为强密码 - XXL-Job admin 密码已从
123456修改为强密码 - XXL-Job accessToken 已从
default_token修改为随机字符串 - Nacos 登录密码已从
nacos修改为强密码 - Canal MySQL 用户密码已从
canal123修改为强密码 - 商城管理后台超级管理员密码已修改为强密码
- Nacos 中的
datasource-multiple.yml使用的是新的 MySQL 密码 - K8s ConfigMap 中所有密码均为修改后的新密码
安全组规则
在阿里云 ECS 安全组中配置入方向规则:
公网入方向(仅开放必要端口):
| 端口 | 授权对象 | 说明 |
|---|---|---|
| 80 / 443 | 0.0.0.0/0 | HTTP / HTTPS(所有人可访问) |
| 22 | <办公网络IP>/32 | SSH(仅限办公 IP) |
内网入方向:
| 端口 | 授权对象 | 说明 |
|---|---|---|
| 全部 | VPC 网段(如 10.0.0.0/8) | 中间件与应用内网互通 |
中间件端口(3306、6379、8848、9876、8080、8082、9000、9001、18083、9200 等)绝不对公网开放。 运维人员通过 SSH 登录到服务器后在内网访问管理页面,或通过 SSH 端口转发。
Nginx 安全加固
在 /etc/nginx/nginx.conf 的 http 块中添加:
# 隐藏版本号
server_tokens off;
# API 限速
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
在 vortmall.conf 的 HTTPS server 块中添加 API 限速:
location /api {
limit_req zone=api burst=60 nodelay;
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;
}
六、日常运维
K8s 操作速查表
| 操作 | 命令 |
|---|---|
| 查看所有 Pod | kubectl get pods -n vortmall |
| 查看服务日志(实时) | 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 top pods -n vortmall |
| 进入容器 | kubectl exec -it <pod名> -n vortmall -- sh |
| 查看 Pod 详情 | kubectl describe pod <pod名> -n vortmall |
| 查看部署状态 | cd /opt/vortmall/k8s && bash deploy.sh --status |
版本升级流程
# 1. 备份数据库
docker exec mysql-8 mysqldump -uroot -p<密码> --all-databases --single-transaction --quick | gzip > backup_$(date +%Y%m%d).sql.gz
# 2. 执行增量 SQL(如版本更新包含数据库变更)
docker exec -i mysql-8 mysql -uroot -p<密码> < db/update/update.sql
# 3. 在开发机构建新版本镜像
cd deployment/k8s
TAG=v1.1.0 bash build.sh
# 4. 传输新镜像到应用服务器并导入
docker save $(docker images --format '{{.Repository}}:{{.Tag}}' | grep vortmall/ | grep v1.1.0) | gzip > vortmall-v1.1.0.tar.gz
scp vortmall-v1.1.0.tar.gz root@<应用服务器IP>:/opt/vortmall/
ssh root@<应用服务器IP> "gunzip -c /opt/vortmall/vortmall-v1.1.0.tar.gz | k3s ctr images import -"
# 5. 滚动更新(以 order 服务为例)
kubectl set image deployment/vortmall-biz-order \
vortmall-biz-order=vortmall/vortmall-biz-order:v1.1.0 \
-n vortmall
# 6. 监控更新进度
kubectl rollout status deployment/vortmall-biz-order -n vortmall
回滚
# K8s 回滚到上一版本
kubectl rollout undo deployment/vortmall-biz-order -n vortmall
# 数据库回滚(从备份恢复)
gunzip < backup_20260327.sql.gz | docker exec -i mysql-8 mysql -uroot -p<密码>
数据库备份
建议配置 cron 定时任务,每天凌晨 3 点自动备份,保留 7 天:
# 编辑 crontab
crontab -e
# 添加以下行
0 3 * * * docker exec mysql-8 mysqldump -uroot -p<密码> --all-databases --single-transaction --quick | gzip > /opt/vortmall/backup/db_$(date +\%Y\%m\%d).sql.gz && find /opt/vortmall/backup -name "db_*.sql.gz" -mtime +7 -delete
# 创建备份目录
mkdir -p /opt/vortmall/backup
磁盘清理
# 清理 7 天前的无用 Docker 镜像
docker image prune -a --filter "until=168h" -f
# 清理 Docker 构建缓存
docker builder prune -f
# 清理过期日志
find /opt/vortmall -name "*.log" -mtime +7 -delete
七、常见问题
Pod CrashLoopBackOff(连不上中间件)
Java 应用启动失败,日志中出现 Connection refused 或 Nacos connected failed。
kubectl logs <pod名称> -n vortmall --tail=50
| 日志关键词 | 原因 | 解决 |
|---|---|---|
Connection refused | 中间件未启动或地址错误 | 检查 ConfigMap 中的地址,确认中间件已启动 |
Access denied | 数据库账号密码错误 | 检查 ConfigMap 的 DB_PASSWORD 与实际 MySQL 密码是否一致 |
No DataSource | 数据库未初始化 | 确认步骤 6 的 SQL 已导入 |
Nacos connected failed | Nacos 地址或命名空间不匹配 | 检查 ConfigMap 的 NACOS_ADDR 和 NACOS_NAMESPACE(应为 public) |
OutOfMemoryError | 内存 limit 太低 | 调高服务 YAML 中 resources.limits.memory |
前端页面空白 / 404
# 检查前端 Pod 是否运行
kubectl get pods -n vortmall | grep 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
Nacos 服务列表为空
# 确认命名空间 ID 为 public
curl -s 'http://<中间件IP>:8848/nacos/v1/console/namespaces'
# 从应用服务器测试到 Nacos 的连通性
# 8848: HTTP 端口, 9848: gRPC 端口(必须都通)
telnet <中间件IP> 8848
telnet <中间件IP> 9848
MySQL 连接数耗尽
docker exec mysql-8 mysql -uroot -p<密码> -e "SHOW STATUS LIKE 'Threads_connected';"
docker exec mysql-8 mysql -uroot -p<密码> -e "SHOW PROCESSLIST;"
# 临时增加连接数上限
docker exec mysql-8 mysql -uroot -p<密码> -e "SET GLOBAL max_connections = 500;"
17 个微服务 × 默认连接池 10 个 = 170 个连接。MySQL 默认
max_connections=151可能不够,建议在 MySQL 配置中设为300以上。
附录 A:端口速查表
中间件端口(中间件服务器)
| 服务 | 端口 | 说明 |
|---|---|---|
| MySQL | 3306 | 数据库 |
| Redis | 6379 | 缓存 |
| 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) | MQTT 消息 |
| Elasticsearch | 9200, 9300 | 搜索引擎 |
| Kibana | 5601 | ES 可视化 |
| Logstash | 5001, 5044 | 日志收集 |
| Canal | 11111, 11112 | 数据同步 |
| SkyWalking OAP | 11800, 12800 | 链路追踪 |
| SkyWalking UI | 18080 | 链路追踪界面 |
应用服务端口(应用服务器 K8s)
| 服务 | 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 | - | 认证授权、Token 签发 |
| 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 | 收银台、门店 |
赣公网安备36010902001041号