资讯详情

JDShop在线购物系统云上部署实战:Docker Compose与避坑指南

📅 2026/10/12 23:15:15 | 华诺云谱 👁 阅读
JDShop在线购物系统云上部署实战:Docker Compose与避坑指南
简介这份资源围绕「在线购物系统云上部署JDShop」展开面向云服务器与Linux运维初学者、计算机专业学生及需要快速搭建电商演示环境的开发者帮助解决从代码上传到数据库配置、域名绑定与安全加固的完整落地问题。压缩包共175个文件约4.59MB以31个php业务脚本、17个css与8个js前端资源、78个png和37个jpg页面素材为主另含1个sql建库脚本、2个txt说明及1个md文档覆盖前端展示、后端逻辑与数据库初始化等模块。已有190人学习下载。资源提供可直接导入的数据库文件与includes目录配置示例读者可据此完成环境准备、权限设置、HTTPS启用及防火墙规则配置并借助页面样式与图片素材理解JDShop的目录组织适合作为云上部署与网络服务配置的实操参考。1. 从一台跑不起来的 JDShop 说起在线购物系统上云到底卡在哪本地mvn spring-boot:run能跑通商品列表、购物车、下单流程都正常一放到云服务器上就出问题——这是很多做 JDShop 在线购物系统云上部署的人遇到的第一个下马威。数据库连不上、静态资源 404、支付回调超时、Session 丢失每一个都能让你在深夜对着日志怀疑人生。JDShop 这类在线购物系统的部署难点从来不在代码本身而在于它天然是一个多组件、有状态、依赖外部服务的分布式应用前端要 Nginx 托管后端 Spring Boot 要连 MySQL 和 Redis图片要存对象存储订单还要对接支付网关。把这些东西从一台开发机搬到云上涉及网络、权限、持久化、安全组、反向代理等一连串配置任何一环没对齐整个链路就断。这篇笔记面向的是已经拿到 JDShop 源码、准备把它部署到云服务器上跑通的开发者不管你是第一次上云还是被某个环节卡住下面从架构拆解到逐步落地再到踩坑排查都会给出可以直接抄的命令和参数。2. JDShop 云上部署的架构拆解与选型决策2.1 在线购物系统的组件依赖关系JDShop 这类在线购物系统典型的技术栈是 Spring Boot MyBatis MySQL Redis Nginx前端可能是 Vue 或 Thymeleaf 模板。部署到云上之前先把组件之间的依赖关系画清楚否则你会陷入“改了 A 结果 B 挂了”的循环。核心依赖链是这样的Nginx 作为入口接收 80/443 端口的请求静态资源JS、CSS、图片直接由 Nginx 返回动态请求反向代理到后端 Spring Boot 应用的 8080 端口。Spring Boot 启动时需要连接 MySQL3306做数据持久化连接 Redis6379做缓存和 Session 共享。如果 JDShop 有文件上传功能图片通常存本地磁盘或对象存储存本地的话要考虑云盘挂载和备份。这里有一个容易忽略的点Spring Boot 的启动顺序。如果 MySQL 还没就绪应用启动时连接池初始化就会失败直接抛CommunicationsException。所以部署脚本里一定要加健康检查确认 MySQL 和 Redis 都 ready 之后再启动后端。2.2 云服务器规格与中间件选型选服务器不是越大越好但也不能抠。JDShop 这种在线购物系统最低配置建议 2 核 4GMySQL 和 Redis 跟应用同机部署的话内存至少 4G否则 JVM 堆内存加上 MySQL 缓冲池会把内存吃满触发 OOM Killer 把 MySQL 进程杀掉——这个血泪经验后面避坑章节还会细说。操作系统选 Ubuntu 22.04 或 CentOS 7两者对 Docker 和主流中间件的支持都成熟。MySQL 版本建议 8.0Redis 建议 6.x 以上JDK 用 17Spring Boot 3.x 要求或 8Spring Boot 2.x。这些版本不是随便定的MySQL 8.0 默认字符集是 utf8mb4避免商品名称里的 emoji 或特殊字符插入报错Redis 6.x 支持 ACL可以给 JDShop 单独建一个受限用户不用默认的 default 账户裸奔。如果预算允许把 MySQL 和 Redis 拆到独立的云数据库服务上应用服务器只跑 Spring Boot 和 Nginx。这样做的好处是备份、监控、扩容都由云厂商托管坏处是网络延迟增加需要在 Spring Boot 的application.yml里把连接超时和重试参数调大。2.3 部署方式选择手动 vs Docker Compose手动部署apt 装 MySQL、Redisjar 包直接 java -jar 启动适合第一次部署、想搞清楚每个组件怎么配的人。Docker Compose 适合需要反复重建环境、或者要同时维护多套环境测试、预发、生产的场景。我一般推荐先用 Docker Compose 把整套环境跑通因为 JDShop 的依赖组件多手动装容易漏配置。Compose 文件里把 MySQL、Redis、后端、Nginx 四个服务定义清楚网络用自定义 bridge数据卷挂到宿主机持久化。等跑通之后再根据实际需求决定要不要拆成手动管理。下面是一个最小可用的docker-compose.yml骨架version: 3.8 services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PWD} MYSQL_DATABASE: jdshop volumes: - ./data/mysql:/var/lib/mysql - ./init.sql:/docker-entrypoint-initdb.d/init.sql ports: - 127.0.0.1:3306:3306 # 只监听本地不暴露公网 healthcheck: test: [CMD, mysqladmin, ping, -h, localhost] interval: 10s retries: 5 redis: image: redis:6.2 command: redis-server --requirepass ${REDIS_PWD} volumes: - ./data/redis:/data ports: - 127.0.0.1:6379:6379 app: build: . depends_on: mysql: condition: service_healthy redis: condition: service_started environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/jdshop?useSSLfalseserverTimezoneAsia/Shanghai SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: ${MYSQL_ROOT_PWD} SPRING_REDIS_HOST: redis SPRING_REDIS_PASSWORD: ${REDIS_PWD} ports: - 127.0.0.1:8080:8080 nginx: image: nginx:1.24 volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf - ./static:/usr/share/nginx/html/static ports: - 80:80 - 443:443 depends_on: - app这段 Compose 文件的关键设计点MySQL 和 Redis 的端口只绑定127.0.0.1不暴露到公网避免被扫描爆破depends_on配合healthcheck确保 MySQL 真正就绪后才启动后端数据库初始化 SQL 通过docker-entrypoint-initdb.d自动执行省去手动导入。环境变量用.env文件管理不要把密码硬编码在 Compose 里提交到代码仓库。3. 从零把 JDShop 跑在云服务器上的完整操作链3.1 服务器初始化与安全组配置拿到一台全新的云服务器后先做三件事更新系统、创建非 root 用户、配置 SSH 密钥登录。不要用 root 直接跑应用这是底线。# 更新系统包 apt update apt upgrade -y # 创建部署用户 adduser deploy usermod -aG sudo deploy # 把 SSH 公钥拷过去在本地执行 ssh-copy-id deployyour-server-ip # 禁用 root 密码登录编辑 /etc/ssh/sshd_config # PermitRootLogin no # PasswordAuthentication no systemctl restart sshd安全组规则只开三个端口22SSH最好限制来源 IP、80HTTP、443HTTPS。MySQL 的 3306 和 Redis 的 6379 绝对不要在安全组里开放即使你觉得“就开一会儿调试”。公网扫描器发现开放数据库端口到发起爆破间隔可能只有几分钟。3.2 MySQL 与 Redis 的容器化启动与初始化在服务器上安装 Docker 和 Docker Compose 插件curl -fsSL https://get.docker.com | sh apt install docker-compose-plugin -y把 JDShop 的建表 SQL 放到init.sql然后启动 MySQL 和 Redis# 创建 .env 文件写入密码 cat .env EOF MYSQL_ROOT_PWDYourStrongPwd123! REDIS_PWDAnotherStrongPwd456! EOF # 只启动 mysql 和 redis docker compose up -d mysql redis # 查看启动日志确认没有报错 docker compose logs -f mysqlMySQL 首次启动会执行init.sql建库建表。如果 SQL 文件很大启动时间会拉长healthcheck的retries要相应调大。Redis 启动后用docker compose exec redis redis-cli -a $REDIS_PWD ping验证返回PONG才算就绪。3.3 后端 jar 包构建与容器化部署JDShop 的 Spring Boot 项目在本地或 CI 环境构建 jar 包# 在项目根目录执行 ./mvnw clean package -DskipTests # 产物在 target/ 下确认 jar 包存在 ls target/*.jar写一个简单的Dockerfile把 jar 包打进去FROM eclipse-temurin:17-jre WORKDIR /app COPY target/jdshop-*.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -Xms512m, -Xmx1024m, -jar, app.jar]-Xms和-Xmx根据服务器内存调整。2 核 4G 的机器上JVM 堆给 1G 左右留足够内存给 MySQL 和系统。如果堆设太大MySQL 的 InnoDB 缓冲池就不够用查询性能反而下降。构建并启动docker compose build app docker compose up -d app docker compose logs -f app看到Started JdShopApplication in X seconds就说明后端起来了。如果卡在HikariPool连接超时检查 MySQL 容器是否 healthy、SPRING_DATASOURCE_URL里的主机名是否写成了mysqlCompose 内部 DNS 解析的服务名。3.4 Nginx 反向代理与静态资源托管Nginx 配置的核心是把/api/路径转发到后端其余静态资源直接返回server { listen 80; server_name your-domain.com; root /usr/share/nginx/html; index index.html; location /static/ { expires 30d; add_header Cache-Control public, immutable; } location /api/ { proxy_pass http://app:8080/; 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 $scheme; proxy_read_timeout 60s; } location / { try_files $uri $uri/ /index.html; } }proxy_read_timeout默认 60 秒如果 JDShop 有导出报表之类的慢接口要调大。try_files那行是给前端 SPA 用的刷新页面不会 404。静态资源加expires和Cache-Control减少重复请求。启动 Nginx 后用curl -I http://your-domain.com/api/products验证反向代理是否生效。返回 200 且响应体是 JSON 就说明链路通了。4. JDShop 云上部署的避坑与排查清单4.1 数据库连接池耗尽导致下单接口超时现象商品列表能打开但下单接口偶尔返回 500日志里出现HikariPool-1 - Connection is not available, request timed out after 30000ms。原因JDShop 的下单逻辑在一个事务里做了多次数据库操作扣库存、写订单、写订单明细、更新用户积分如果连接池最大连接数设得太小默认 10并发一上来连接就被占满后续请求排队等 30 秒后超时。解决在application.yml里调大 HikariCP 的maximum-pool-size一般设为 CPU 核数 × 2 磁盘数2 核机器设 10~15 比较合适。同时检查下单事务里有没有不必要的远程调用比如调支付网关把远程调用挪到事务外面缩短连接持有时间。4.2 Redis 未设密码导致数据被清空现象部署完第二天发现购物车数据全没了Redis 里多了一些奇怪的 key。原因Redis 容器启动时没设requirepass端口又通过安全组暴露到了公网被自动化脚本扫描到后写入垃圾数据或执行FLUSHALL。解决Redis 必须设密码端口只绑定127.0.0.1安全组不开放 6379。如果已经暴露过立刻改密码、清空数据、检查有没有被写入恶意 key。Spring Boot 侧同步更新spring.redis.password。4.3 文件上传路径在容器重启后丢失现象商品图片上传成功但容器重启后图片全部 404。原因上传目录没有挂载到宿主机卷容器重建时文件系统重置文件全丢。解决在docker-compose.yml里给 app 服务加 volumes 映射把上传目录挂到宿主机./data/upload:/app/upload。同时检查 JDShop 配置文件里的上传路径是否指向这个目录。更稳妥的方案是接对象存储但那是另一个话题了。4.4 Nginx 转发后后端拿不到真实客户端 IP现象后台日志里所有请求的 IP 都是 Docker 内网地址172.x.x.x风控和限流逻辑失效。原因Nginx 反向代理后后端看到的remoteAddr是 Nginx 容器的 IP不是真实客户端 IP。解决Nginx 配置里加proxy_set_header X-Real-IP $remote_addr和X-Forwarded-For后端用X-Forwarded-For的第一个 IP 作为客户端 IP。Spring Boot 里可以配server.forward-headers-strategy: native让框架自动处理。4.5 JVM 堆内存过大触发 OOM Killer现象运行一段时间后 MySQL 容器突然挂掉dmesg里看到Out of memory: Killed process mysql。原因JVM 默认堆内存是物理内存的 1/44G 机器上 JVM 可能吃掉 1G加上 MySQL 的 InnoDB 缓冲池默认 128M 但实际运行会涨再算上系统和其他进程内存不够时 Linux 的 OOM Killer 会挑内存占用大的进程杀MySQL 往往首当其冲。解决显式设置 JVM 的-Xmx为 1G 左右MySQL 的innodb_buffer_pool_size设为 512M~1G给系统留至少 512M。用docker stats监控各容器内存占用发现异常及时调整。5. 让 JDShop 部署可复现的一个关键习惯部署跑通只是开始真正省时间的是把整个过程变成可重复执行的脚本。我现在的习惯是所有配置——Compose 文件、Nginx 配置、初始化 SQL、环境变量模板——全部放进一个deploy/目录用 Git 管理。每次换服务器或者重建环境只需要git clonedocker compose up -d十分钟内就能拉起一套完整环境。验证部署是否成功不要只看容器状态。按这个顺序过一遍docker compose ps确认所有服务 Upcurl http://localhost/api/products确认后端返回数据浏览器打开首页走一遍加购到下单的流程最后docker compose logs --tail50扫一眼有没有 ERROR 级别的日志。这套检查流程花不了五分钟但能挡住大部分“看起来起来了实际不能用”的情况。还有一个后悔药级别的建议在云控制台给服务器磁盘开自动快照每天一次保留七天。JDShop 的数据库文件、上传的图片、Nginx 配置都在磁盘上万一误操作或者被攻击快照能让你回滚到前一天的状态。这个成本很低但关键时刻能救命。部署这件事第一次做会觉得琐碎做多了就会发现套路固定网络通、依赖就绪、配置对齐、持久化到位。把这四件事按顺序检查一遍大部分问题都能定位。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑