1. 项目概述从源码到服务的最后一公里做Java后端开发尤其是基于Spring Boot这类框架项目开发完只是第一步。怎么把它变成一个稳定、可运维的服务才是真正考验功力的地方。最近在折腾一个基于Jeecg-boot框架的项目从开发环境到生产部署踩了不少坑也总结了一套相对稳妥的jar包部署方案。Jeecg-boot本身是个不错的快速开发平台但它的前后端分离架构让部署变得稍微有点“绕”——前端是Vue打包的静态资源后端是Spring Boot的jar包两者需要协同工作。网上教程很多但要么太简略要么环境对不上实操起来总差那么点意思。今天我就把自己从打包、配置到上线运维的全过程包括那些容易掉进去的坑掰开揉碎了讲清楚。无论你是刚接手Jeecg-boot项目的新手还是想优化现有部署流程的老鸟这篇从实战中来的总结应该都能给你提供一条清晰的路径。2. 部署方案全景与核心思路拆解在动手之前我们必须先搞清楚我们要部署的到底是什么以及有哪几种路可以走。Jeecg-boot是一个典型的前后端分离项目后端jeecg-boot是一个Spring Boot应用提供RESTful API前端jeecg-boot-vue3或ant-design-vue-jeecg是一个Vue.js项目编译后生成HTML、CSS、JavaScript等静态文件。部署的核心目标就是让用户通过浏览器能访问到前端页面并且前端页面能正确调用后端API。2.1 主流部署模式对比通常有三种部署模式各有优劣模式一完全分离部署这是最“教科书”式的做法。前端静态资源部署在一个Nginx或Apache服务器上后端Jar包独立运行在一台或多台Java服务器上。前端通过配置Nginx反向代理将/api等路径的请求转发到后端服务器。优点前后端完全解耦可以独立伸缩、升级。前端可以利用CDN加速后端可以方便地做集群。缺点部署复杂度高需要维护至少两个服务且需要处理跨域CORS问题虽然可以在Nginx或后端解决。适用场景中大型项目对性能、可用性要求高有专业的运维团队。模式二后端内嵌前端资源这也是Spring Boot官方推荐和支持的方式。将前端编译后的dist目录下的所有文件拷贝到后端项目的src/main/resources/static或public目录下。然后打包成一个统一的Jar包。Spring Boot内置的Tomcat会同时服务于前端静态资源和后端API。优点部署极度简化只有一个Jar包运维成本低。天然同源无跨域烦恼。缺点前后端耦合任何前端改动都需要重新打包整个Jar包。静态资源由Tomcat服务在高并发静态资源请求下性能不如专业的Nginx。适用场景中小型项目内部管理系统追求部署简便迭代速度不是特别快。模式三混合部署本文重点这是一种折中方案。前端和后端仍然独立打包前端是dist压缩包或目录后端是Jar包。但它们被部署在同一台服务器的约定目录下通过一个统一的启动脚本或配置比如使用Nginx同时代理静态资源和后端API对外提供一个统一的访问入口。优点兼顾了分离部署的灵活性和内嵌部署的简便性。前端可以独立更新替换dist文件后端也可以独立重启。利用Nginx处理静态资源性能更好。缺点比纯内嵌部署多一步Nginx的配置。适用场景绝大多数Jeecg-boot项目的生产环境选择在便捷性和灵活性之间取得了很好的平衡。对于Jeecg-boot项目我强烈推荐模式三。模式一对于大多数项目来说过于重型模式二在频繁更新前端时略显笨拙。模式三既能利用Nginx的高效静态文件处理能力又能保持前后端发布的一定独立性是实践中的“甜点”。2.2 技术栈与工具选型确定了模式我们来看看需要哪些工具打包工具后端依赖Maven或Gradle前端依赖Node.js和npm/yarn/pnpm。这是基础。服务器环境Linux如CentOS 7/8, Ubuntu 20.04。生产环境首选。Web服务器Nginx。负责托管前端静态文件并反向代理后端API请求。其高性能、低内存占用和灵活的配置使其成为不二之选。应用服务器JDK。运行Spring Boot Jar包。版本需与项目要求匹配Jeecg-boot通常需要JDK 8或11。进程管理systemd或Supervisor。用于将Java应用作为系统服务管理实现开机自启、自动重启、日志管理。这里我们选用Linux系统自带的systemd它更原生、更通用。部署方式手动SCP上传或使用CI/CD工具如Jenkins、GitLab CI。本文先涵盖手动部署的全流程这是理解自动化基础的关键。注意很多新手会纠结于在IDEA里直接点“Run”或者用“java -jar”临时测试与正式部署的区别。开发环境运行是为了调试而生产部署追求的是稳定、可靠、可监控、可维护。直接命令行启动一个Jar包终端一关服务就没了这绝对不行。我们必须将其转化为一个守护进程Daemon。3. 步步为营前后端打包实操详解部署的第一步是获得可部署的“工件”。这一步的规范性直接决定了后续部署的顺利程度。3.1 后端Jar包打包与关键配置后端的打包核心是Maven。在项目根目录包含pom.xml的目录下执行打包命令mvn clean package -DskipTestsclean清理旧的编译输出。package执行编译、测试、打包生命周期。-DskipTests跳过单元测试加快打包速度。生产打包前请确保已在本地或测试环境充分运行过测试。执行成功后你会在项目根目录/target/下找到生成的Jar包名称通常为jeecg-boot-xxx.jarxxx是版本号。打包的“黑盒”与避坑点配置文件隔离这是最重要的原则。Spring Boot的application.yml或application.properties中通常包含数据库密码、Redis地址、加密密钥等敏感信息。绝对不要将这些信息写死在打包进Jar的资源文件中。正确做法是使用外部化配置。在application.yml中只保留不敏感的、开发环境通用的配置如一些功能开关。将生产环境的配置如spring.datasource.url,spring.redis.host单独写在一个文件里例如application-prod.yml。打包时这个application-prod.yml不打包进Jar。在服务器上将它放在Jar包的同级或特定目录如/opt/app/config/。启动时通过命令行参数指定激活的Profile和配置文件路径java -jar jeecg-boot-xxx.jar --spring.profiles.activeprod --spring.config.location/opt/app/config/依赖冲突排查有时打包会失败提示类似“com.kingbase8:kingbase8:jar:8.6.0 was not found”或“unresolved dependency”。这通常是Maven仓库中缺少某个依赖或者私服配置有问题。首先检查项目的pom.xml和父POM中的仓库配置是否正确特别是如果使用了公司私服。尝试在本地执行mvn dependency:resolve查看依赖解析情况。对于确实无法从仓库下载的Jar如某些商业数据库驱动需要手动安装到本地仓库mvn install:install-file或上传到私服。打包结果验证不要以为打出Jar包就万事大吉。可以用以下命令快速验证Jar包结构# 查看Jar包内容列表看静态资源、配置文件是否在内 jar -tf jeecg-boot-xxx.jar | head -20 # 解压查看谨慎使用了解即可通常不用解压运行 # jar -xvf jeecg-boot-xxx.jar这里提到了热词中的jar -xvf是什么意思-x表示解压-v表示显示详细过程-f指定Jar文件。这是一个诊断命令用于查看Jar包内部结构但Spring Boot的Jar包是“可执行Jar”有特殊的启动加载器通常不应该解压运行。3.2 前端资源构建与优化前端项目通常在独立的目录中。以Vue3版本为例# 1. 进入前端项目目录 cd jeecg-boot-vue3 # 2. 安装依赖建议使用pnpm或yarn速度更快 pnpm install # 或 npm install --registryhttps://registry.npmmirror.com 使用国内镜像 # 3. 构建生产环境产物 pnpm run build:prod # 或 npm run build:prod构建成功后会在项目根目录下生成dist文件夹。这个文件夹里的内容就是我们需要部署到Nginx下的静态资源。前端构建的注意事项环境变量与API地址前端需要知道后端API的地址。Jeecg-boot前端通常通过配置文件如.env.production或构建时注入的全局变量来设置。务必检查dist生成后其中包含的JavaScript文件里API请求的基地址Base URL是否正确指向了你将要部署的后端地址例如/prod-api或http://your-api-server:8080。错误的API地址会导致前端页面白屏或接口调用失败。路由模式与404问题Vue Router默认使用history模式这种模式需要服务器端配合。如果你将dist直接扔到Nginx根目录直接访问首页没问题但刷新非首页的子路由页面Nginx会返回404因为它会把这个路由路径当作一个真实的文件路径去查找。解决方案是在Nginx配置中添加try_files指令下文会详细说明。构建产物分析对于大型项目可以使用pnpm run build:prod --report生成构建分析报告查看哪些模块体积过大以便进行优化。4. 服务器环境准备与部署编排假设我们有一台全新的CentOS 7服务器IP为192.168.1.100。我们需要按顺序完成以下准备工作。4.1 基础环境安装# 1. 更新系统 yum update -y # 2. 安装JDK (以JDK 11为例) yum install -y java-11-openjdk-devel # 验证安装 java -version # 3. 安装Nginx yum install -y epel-release yum install -y nginx # 启动并设置开机自启 systemctl start nginx systemctl enable nginx # 验证浏览器访问 http://服务器IP应看到Nginx欢迎页 # 4. 创建应用目录结构 mkdir -p /opt/jeecg/{app,frontend,logs,config} # /opt/jeecg/app: 存放后端Jar包 # /opt/jeecg/frontend: 存放前端dist资源 # /opt/jeecg/logs: 存放应用日志 # /opt/jeecg/config: 存放外部配置文件4.2 部署文件上传与放置将你在本地打包好的文件上传到服务器对应目录后端将jeecg-boot-xxx.jar上传到/opt/jeecg/app/前端将本地dist文件夹内的所有内容通常是index.html和static等文件夹上传到/opt/jeecg/frontend/配置将准备好的application-prod.yml上传到/opt/jeecg/config/你可以使用scp命令或SFTP工具如FileZilla完成上传。# 示例从本地传输文件到服务器 scp ./target/jeecg-boot-xxx.jar root192.168.1.100:/opt/jeecg/app/ scp -r ./dist/* root192.168.1.100:/opt/jeecg/frontend/ scp ./application-prod.yml root192.168.1.100:/opt/jeecg/config/4.3 配置Nginx作为统一入口这是混合部署模式的核心。我们需要配置Nginx让它拦截所有请求。如果是请求静态资源如.js,.css,.png,.ico则从/opt/jeecg/frontend目录提供。如果是请求API如以/api,/jeecg-boot开头的路径则转发到后端Spring Boot应用假设运行在8080端口。处理Vue Router的history模式。编辑Nginx配置文件通常位于/etc/nginx/nginx.conf或/etc/nginx/conf.d/default.conf。建议在conf.d下新建一个专用配置如jeecg.conf。vi /etc/nginx/conf.d/jeecg.conf写入以下配置server { listen 80; server_name your-domain.com; # 改为你的域名或服务器IP # 前端静态资源目录 root /opt/jeecg/frontend; index index.html index.htm; # 开启gzip压缩提升传输效率 gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xmlrss text/javascript; # 核心配置处理静态资源和API代理 location / { # 针对Vue Router的history模式如果请求的文件不存在则返回index.html try_files $uri $uri/ /index.html; } # 代理后端API请求 # Jeecg-boot默认的API上下文路径是 /jeecg-boot location /jeecg-boot { # 转发到本地的Spring Boot应用 proxy_pass http://127.0.0.1:8080/jeecg-boot; 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_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # 如果你还有其他API路径可以继续添加 # location /api { # proxy_pass http://127.0.0.1:8080/api; # ... 其他proxy_set_header配置同上 # } # 可选的静态资源缓存设置提升性能 location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control public, immutable; } # 错误页面配置可选 error_page 404 /index.html; error_page 500 502 503 504 /50x.html; location /50x.html { root /usr/share/nginx/html; } }保存并退出后检查Nginx配置语法并重载配置nginx -t # 测试配置语法 systemctl reload nginx # 重载配置使生效现在访问http://服务器IPNginx应该能正确展示前端页面了。但此时API请求会失败因为后端服务还没启动。4.4 配置systemd服务管理后端应用我们使用systemd来管理Spring Boot应用这是生产环境的标准做法。创建服务单元文件vi /etc/systemd/system/jeecg.service写入以下内容[Unit] DescriptionJeecg-Boot Application Service Afternetwork.target syslog.target [Service] Typesimple Userroot # 生产环境建议使用非root用户如 appuser WorkingDirectory/opt/jeecg/app ExecStart/usr/bin/java -Xms512m -Xmx1024m -jar /opt/jeecg/app/jeecg-boot-xxx.jar --spring.profiles.activeprod --spring.config.locationfile:/opt/jeecg/config/ SuccessExitStatus143 # 重要配置日志由systemd的journalctl管理 StandardOutputjournal StandardErrorjournal # 环境变量可选也可在config/application-prod.yml中配置 # EnvironmentJAVA_OPTS-Xms512m -Xmx1024m # 进程管理策略 Restarton-failure RestartSec10 [Install] WantedBymulti-user.target关键参数解析与调优经验-Xms512m -Xmx1024m设置JVM堆内存初始值和最大值。这是必须根据服务器实际内存调整的对于一般的管理系统1G-2G的堆内存是常见的起点。可以通过监控工具如jstat观察GC情况来调整。--spring.config.locationfile:/opt/jeecg/config/指定外部配置文件目录。file:前缀很重要。Spring Boot会加载这个目录下的application-prod.yml因为激活了prodprofile和application.yml如果有。WorkingDirectory设置工作目录。这样应用生成的临时文件、日志如果配置了相对路径都会在这个目录下便于管理。Restarton-failure当进程异常退出时自动重启。这是保障服务高可用的关键配置。日志这里配置了输出到systemd journal。你也可以修改Spring Boot的logback-spring.xml配置将日志文件输出到/opt/jeecg/logs/目录便于用tail、cat或ELK等工具查看。我强烈建议使用文件日志并配置日志滚动RollingFileAppender。保存后启用并启动服务systemctl daemon-reload # 重载systemd配置 systemctl enable jeecg.service # 设置开机自启 systemctl start jeecg.service # 启动服务 systemctl status jeecg.service # 查看服务状态如果状态显示active (running)恭喜你后端服务也启动成功了。现在再次访问http://服务器IP整个Jeecg-boot应用应该可以正常登录和操作了。5. 部署后运维、监控与问题排查部署上线不是终点而是运维的起点。下面是一些确保服务稳定运行的关键操作。5.1 基础运维命令掌握这些命令足以应对日常运维# 查看应用实时日志如果你配置了文件日志 tail -f /opt/jeecg/logs/jeecg.log # 查看systemd管理的服务日志 journalctl -u jeecg.service -f # -f 表示跟踪输出 # 服务管理 systemctl stop jeecg.service # 停止 systemctl start jeecg.service # 启动 systemctl restart jeecg.service # 重启先停后启 systemctl reload jeecg.service # 重载对于Spring Boot通常无效需重启 systemctl status jeecg.service # 状态 # 查看进程和资源占用 ps aux | grep jeecg-boot # 查看Java进程 top -p $(pgrep -f jeecg-boot) # 动态监控该进程资源5.2 常见问题与排查技巧实录即使按照步骤操作也难免会遇到问题。这里记录几个我踩过的坑和排查思路。问题1前端页面白屏浏览器控制台报404或网络错误。排查思路检查Nginx服务systemctl status nginx确认Nginx正在运行。检查静态资源直接在浏览器访问一个静态文件如http://服务器IP/static/js/app.xxx.js。如果404说明Nginx的root目录配置错误或者文件没上传到位。用ls -la /opt/jeecg/frontend/static/检查。检查API代理在浏览器控制台查看具体哪个API请求失败了。然后直接在服务器上用curl测试后端接口curl http://127.0.0.1:8080/jeecg-boot/sys/login假设有个登录接口。如果curl能通但前端不通问题在Nginx代理配置检查location /jeecg-boot的proxy_pass地址和端口。如果curl也不通问题在后端服务。检查后端服务systemctl status jeecg.service和journalctl -u jeecg.service -n 50查看后端日志看是否启动成功是否有数据库连接失败等异常。问题2后端服务启动失败状态为failed。排查思路查看详细日志journalctl -u jeecg.service -xe查看最详细的错误信息。常见原因端口占用Address already in use。Spring Boot默认端口8080可能被其他进程占用。用netstat -tlnp | grep :8080查看修改application-prod.yml中的server.port或停止占用进程。配置文件错误YAML格式错误、数据库连接字符串错误、Redis连接失败。仔细检查/opt/jeecg/config/application-prod.yml的语法和内容。一个技巧可以先在命令行用java -jar ...的方式手动启动看看输出更容易定位问题。内存不足JVM无法分配指定的-Xmx内存。调小-Xmx参数或检查服务器剩余内存free -h。依赖缺失虽然打包成Jar但运行时如果依赖了本地库如某些加密狗驱动可能缺失。检查日志中是否有ClassNotFoundException或NoClassDefFoundError。问题3服务运行一段时间后响应变慢或内存占用过高。排查思路监控JVM使用jstat -gc pid 1000 10查看GC情况。如果Full GC频繁说明可能存在内存泄漏或堆内存设置过小。生成堆转储在jeecg.service的ExecStart行添加JVM参数-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/opt/jeecg/logs/以便在内存溢出时自动生成堆转储文件用MAT等工具分析。检查应用日志是否有大量的异常堆栈特别是数据库查询慢日志如果配置了。检查服务器资源使用top,vmstat 1,iostat -x 1查看CPU、内存、IO瓶颈。问题4如何优雅更新版本标准流程在服务器上将新的Jar包如jeecg-boot-xxx-new.jar上传到/opt/jeecg/app/目录下。修改jeecg.service文件中的ExecStart行指向新的Jar包文件名。执行systemctl daemon-reload。执行systemctl restart jeecg.service。通过systemctl status和查看日志确认新版本启动成功。更稳妥的做法蓝绿/滚动更新思想新旧Jar包使用不同文件名并存。修改jeecg.service指向新文件后daemon-reload。先systemctl stop旧服务再systemctl start新服务。这样回滚极其快速只需改回文件名并重启。永远保留上一个稳定版本的Jar包和配置文件。5.3 安全与优化建议防火墙配置服务器防火墙如firewalld或iptables只开放80HTTP、443HTTPS如果用了SSL和SSH端口。关闭后端应用端口如8080的外部访问只允许本机127.0.0.1访问由Nginx反向代理。firewall-cmd --permanent --add-servicehttp firewall-cmd --permanent --add-servicehttps firewall-cmd --permanent --remove-port8080/tcp # 确保8080不对外开放 firewall-cmd --reload使用非root用户运行在jeecg.service中将Userroot改为一个新建的普通用户如appuser并确保该用户对/opt/jeecg目录有读写权限。这能降低安全风险。配置HTTPS使用Let‘s Encrypt等工具为域名申请免费SSL证书并在Nginx中配置将HTTP重定向到HTTPS。这是生产环境的必备项。日志轮转使用logrotate工具配置对应用日志文件如/opt/jeecg/logs/jeecg.log进行自动切割、压缩和清理防止日志占满磁盘。部署本身是一个系统工程从打包规范到服务器配置再到日常监控每一个环节都影响着服务的稳定性。对于Jeecg-boot这类项目采用Nginx托管前端独立Jar包运行后端systemd管理的混合模式在复杂度和可控性上达到了很好的平衡。记住每次变更前做好备份修改配置后先测试语法重启服务后紧盯日志。这套流程跑顺了再结合Jenkins、Docker热词中的docker安装部署、idea 怎么发布jar到本地的桌面端docker是另一个维度的优化等工具实现自动化你的部署能力就能再上一个台阶。
Jeecg-Boot项目生产部署实战:Nginx+Jar包+Systemd混合部署方案详解
1. 项目概述从源码到服务的最后一公里做Java后端开发尤其是基于Spring Boot这类框架项目开发完只是第一步。怎么把它变成一个稳定、可运维的服务才是真正考验功力的地方。最近在折腾一个基于Jeecg-boot框架的项目从开发环境到生产部署踩了不少坑也总结了一套相对稳妥的jar包部署方案。Jeecg-boot本身是个不错的快速开发平台但它的前后端分离架构让部署变得稍微有点“绕”——前端是Vue打包的静态资源后端是Spring Boot的jar包两者需要协同工作。网上教程很多但要么太简略要么环境对不上实操起来总差那么点意思。今天我就把自己从打包、配置到上线运维的全过程包括那些容易掉进去的坑掰开揉碎了讲清楚。无论你是刚接手Jeecg-boot项目的新手还是想优化现有部署流程的老鸟这篇从实战中来的总结应该都能给你提供一条清晰的路径。2. 部署方案全景与核心思路拆解在动手之前我们必须先搞清楚我们要部署的到底是什么以及有哪几种路可以走。Jeecg-boot是一个典型的前后端分离项目后端jeecg-boot是一个Spring Boot应用提供RESTful API前端jeecg-boot-vue3或ant-design-vue-jeecg是一个Vue.js项目编译后生成HTML、CSS、JavaScript等静态文件。部署的核心目标就是让用户通过浏览器能访问到前端页面并且前端页面能正确调用后端API。2.1 主流部署模式对比通常有三种部署模式各有优劣模式一完全分离部署这是最“教科书”式的做法。前端静态资源部署在一个Nginx或Apache服务器上后端Jar包独立运行在一台或多台Java服务器上。前端通过配置Nginx反向代理将/api等路径的请求转发到后端服务器。优点前后端完全解耦可以独立伸缩、升级。前端可以利用CDN加速后端可以方便地做集群。缺点部署复杂度高需要维护至少两个服务且需要处理跨域CORS问题虽然可以在Nginx或后端解决。适用场景中大型项目对性能、可用性要求高有专业的运维团队。模式二后端内嵌前端资源这也是Spring Boot官方推荐和支持的方式。将前端编译后的dist目录下的所有文件拷贝到后端项目的src/main/resources/static或public目录下。然后打包成一个统一的Jar包。Spring Boot内置的Tomcat会同时服务于前端静态资源和后端API。优点部署极度简化只有一个Jar包运维成本低。天然同源无跨域烦恼。缺点前后端耦合任何前端改动都需要重新打包整个Jar包。静态资源由Tomcat服务在高并发静态资源请求下性能不如专业的Nginx。适用场景中小型项目内部管理系统追求部署简便迭代速度不是特别快。模式三混合部署本文重点这是一种折中方案。前端和后端仍然独立打包前端是dist压缩包或目录后端是Jar包。但它们被部署在同一台服务器的约定目录下通过一个统一的启动脚本或配置比如使用Nginx同时代理静态资源和后端API对外提供一个统一的访问入口。优点兼顾了分离部署的灵活性和内嵌部署的简便性。前端可以独立更新替换dist文件后端也可以独立重启。利用Nginx处理静态资源性能更好。缺点比纯内嵌部署多一步Nginx的配置。适用场景绝大多数Jeecg-boot项目的生产环境选择在便捷性和灵活性之间取得了很好的平衡。对于Jeecg-boot项目我强烈推荐模式三。模式一对于大多数项目来说过于重型模式二在频繁更新前端时略显笨拙。模式三既能利用Nginx的高效静态文件处理能力又能保持前后端发布的一定独立性是实践中的“甜点”。2.2 技术栈与工具选型确定了模式我们来看看需要哪些工具打包工具后端依赖Maven或Gradle前端依赖Node.js和npm/yarn/pnpm。这是基础。服务器环境Linux如CentOS 7/8, Ubuntu 20.04。生产环境首选。Web服务器Nginx。负责托管前端静态文件并反向代理后端API请求。其高性能、低内存占用和灵活的配置使其成为不二之选。应用服务器JDK。运行Spring Boot Jar包。版本需与项目要求匹配Jeecg-boot通常需要JDK 8或11。进程管理systemd或Supervisor。用于将Java应用作为系统服务管理实现开机自启、自动重启、日志管理。这里我们选用Linux系统自带的systemd它更原生、更通用。部署方式手动SCP上传或使用CI/CD工具如Jenkins、GitLab CI。本文先涵盖手动部署的全流程这是理解自动化基础的关键。注意很多新手会纠结于在IDEA里直接点“Run”或者用“java -jar”临时测试与正式部署的区别。开发环境运行是为了调试而生产部署追求的是稳定、可靠、可监控、可维护。直接命令行启动一个Jar包终端一关服务就没了这绝对不行。我们必须将其转化为一个守护进程Daemon。3. 步步为营前后端打包实操详解部署的第一步是获得可部署的“工件”。这一步的规范性直接决定了后续部署的顺利程度。3.1 后端Jar包打包与关键配置后端的打包核心是Maven。在项目根目录包含pom.xml的目录下执行打包命令mvn clean package -DskipTestsclean清理旧的编译输出。package执行编译、测试、打包生命周期。-DskipTests跳过单元测试加快打包速度。生产打包前请确保已在本地或测试环境充分运行过测试。执行成功后你会在项目根目录/target/下找到生成的Jar包名称通常为jeecg-boot-xxx.jarxxx是版本号。打包的“黑盒”与避坑点配置文件隔离这是最重要的原则。Spring Boot的application.yml或application.properties中通常包含数据库密码、Redis地址、加密密钥等敏感信息。绝对不要将这些信息写死在打包进Jar的资源文件中。正确做法是使用外部化配置。在application.yml中只保留不敏感的、开发环境通用的配置如一些功能开关。将生产环境的配置如spring.datasource.url,spring.redis.host单独写在一个文件里例如application-prod.yml。打包时这个application-prod.yml不打包进Jar。在服务器上将它放在Jar包的同级或特定目录如/opt/app/config/。启动时通过命令行参数指定激活的Profile和配置文件路径java -jar jeecg-boot-xxx.jar --spring.profiles.activeprod --spring.config.location/opt/app/config/依赖冲突排查有时打包会失败提示类似“com.kingbase8:kingbase8:jar:8.6.0 was not found”或“unresolved dependency”。这通常是Maven仓库中缺少某个依赖或者私服配置有问题。首先检查项目的pom.xml和父POM中的仓库配置是否正确特别是如果使用了公司私服。尝试在本地执行mvn dependency:resolve查看依赖解析情况。对于确实无法从仓库下载的Jar如某些商业数据库驱动需要手动安装到本地仓库mvn install:install-file或上传到私服。打包结果验证不要以为打出Jar包就万事大吉。可以用以下命令快速验证Jar包结构# 查看Jar包内容列表看静态资源、配置文件是否在内 jar -tf jeecg-boot-xxx.jar | head -20 # 解压查看谨慎使用了解即可通常不用解压运行 # jar -xvf jeecg-boot-xxx.jar这里提到了热词中的jar -xvf是什么意思-x表示解压-v表示显示详细过程-f指定Jar文件。这是一个诊断命令用于查看Jar包内部结构但Spring Boot的Jar包是“可执行Jar”有特殊的启动加载器通常不应该解压运行。3.2 前端资源构建与优化前端项目通常在独立的目录中。以Vue3版本为例# 1. 进入前端项目目录 cd jeecg-boot-vue3 # 2. 安装依赖建议使用pnpm或yarn速度更快 pnpm install # 或 npm install --registryhttps://registry.npmmirror.com 使用国内镜像 # 3. 构建生产环境产物 pnpm run build:prod # 或 npm run build:prod构建成功后会在项目根目录下生成dist文件夹。这个文件夹里的内容就是我们需要部署到Nginx下的静态资源。前端构建的注意事项环境变量与API地址前端需要知道后端API的地址。Jeecg-boot前端通常通过配置文件如.env.production或构建时注入的全局变量来设置。务必检查dist生成后其中包含的JavaScript文件里API请求的基地址Base URL是否正确指向了你将要部署的后端地址例如/prod-api或http://your-api-server:8080。错误的API地址会导致前端页面白屏或接口调用失败。路由模式与404问题Vue Router默认使用history模式这种模式需要服务器端配合。如果你将dist直接扔到Nginx根目录直接访问首页没问题但刷新非首页的子路由页面Nginx会返回404因为它会把这个路由路径当作一个真实的文件路径去查找。解决方案是在Nginx配置中添加try_files指令下文会详细说明。构建产物分析对于大型项目可以使用pnpm run build:prod --report生成构建分析报告查看哪些模块体积过大以便进行优化。4. 服务器环境准备与部署编排假设我们有一台全新的CentOS 7服务器IP为192.168.1.100。我们需要按顺序完成以下准备工作。4.1 基础环境安装# 1. 更新系统 yum update -y # 2. 安装JDK (以JDK 11为例) yum install -y java-11-openjdk-devel # 验证安装 java -version # 3. 安装Nginx yum install -y epel-release yum install -y nginx # 启动并设置开机自启 systemctl start nginx systemctl enable nginx # 验证浏览器访问 http://服务器IP应看到Nginx欢迎页 # 4. 创建应用目录结构 mkdir -p /opt/jeecg/{app,frontend,logs,config} # /opt/jeecg/app: 存放后端Jar包 # /opt/jeecg/frontend: 存放前端dist资源 # /opt/jeecg/logs: 存放应用日志 # /opt/jeecg/config: 存放外部配置文件4.2 部署文件上传与放置将你在本地打包好的文件上传到服务器对应目录后端将jeecg-boot-xxx.jar上传到/opt/jeecg/app/前端将本地dist文件夹内的所有内容通常是index.html和static等文件夹上传到/opt/jeecg/frontend/配置将准备好的application-prod.yml上传到/opt/jeecg/config/你可以使用scp命令或SFTP工具如FileZilla完成上传。# 示例从本地传输文件到服务器 scp ./target/jeecg-boot-xxx.jar root192.168.1.100:/opt/jeecg/app/ scp -r ./dist/* root192.168.1.100:/opt/jeecg/frontend/ scp ./application-prod.yml root192.168.1.100:/opt/jeecg/config/4.3 配置Nginx作为统一入口这是混合部署模式的核心。我们需要配置Nginx让它拦截所有请求。如果是请求静态资源如.js,.css,.png,.ico则从/opt/jeecg/frontend目录提供。如果是请求API如以/api,/jeecg-boot开头的路径则转发到后端Spring Boot应用假设运行在8080端口。处理Vue Router的history模式。编辑Nginx配置文件通常位于/etc/nginx/nginx.conf或/etc/nginx/conf.d/default.conf。建议在conf.d下新建一个专用配置如jeecg.conf。vi /etc/nginx/conf.d/jeecg.conf写入以下配置server { listen 80; server_name your-domain.com; # 改为你的域名或服务器IP # 前端静态资源目录 root /opt/jeecg/frontend; index index.html index.htm; # 开启gzip压缩提升传输效率 gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xmlrss text/javascript; # 核心配置处理静态资源和API代理 location / { # 针对Vue Router的history模式如果请求的文件不存在则返回index.html try_files $uri $uri/ /index.html; } # 代理后端API请求 # Jeecg-boot默认的API上下文路径是 /jeecg-boot location /jeecg-boot { # 转发到本地的Spring Boot应用 proxy_pass http://127.0.0.1:8080/jeecg-boot; 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_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # 如果你还有其他API路径可以继续添加 # location /api { # proxy_pass http://127.0.0.1:8080/api; # ... 其他proxy_set_header配置同上 # } # 可选的静态资源缓存设置提升性能 location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control public, immutable; } # 错误页面配置可选 error_page 404 /index.html; error_page 500 502 503 504 /50x.html; location /50x.html { root /usr/share/nginx/html; } }保存并退出后检查Nginx配置语法并重载配置nginx -t # 测试配置语法 systemctl reload nginx # 重载配置使生效现在访问http://服务器IPNginx应该能正确展示前端页面了。但此时API请求会失败因为后端服务还没启动。4.4 配置systemd服务管理后端应用我们使用systemd来管理Spring Boot应用这是生产环境的标准做法。创建服务单元文件vi /etc/systemd/system/jeecg.service写入以下内容[Unit] DescriptionJeecg-Boot Application Service Afternetwork.target syslog.target [Service] Typesimple Userroot # 生产环境建议使用非root用户如 appuser WorkingDirectory/opt/jeecg/app ExecStart/usr/bin/java -Xms512m -Xmx1024m -jar /opt/jeecg/app/jeecg-boot-xxx.jar --spring.profiles.activeprod --spring.config.locationfile:/opt/jeecg/config/ SuccessExitStatus143 # 重要配置日志由systemd的journalctl管理 StandardOutputjournal StandardErrorjournal # 环境变量可选也可在config/application-prod.yml中配置 # EnvironmentJAVA_OPTS-Xms512m -Xmx1024m # 进程管理策略 Restarton-failure RestartSec10 [Install] WantedBymulti-user.target关键参数解析与调优经验-Xms512m -Xmx1024m设置JVM堆内存初始值和最大值。这是必须根据服务器实际内存调整的对于一般的管理系统1G-2G的堆内存是常见的起点。可以通过监控工具如jstat观察GC情况来调整。--spring.config.locationfile:/opt/jeecg/config/指定外部配置文件目录。file:前缀很重要。Spring Boot会加载这个目录下的application-prod.yml因为激活了prodprofile和application.yml如果有。WorkingDirectory设置工作目录。这样应用生成的临时文件、日志如果配置了相对路径都会在这个目录下便于管理。Restarton-failure当进程异常退出时自动重启。这是保障服务高可用的关键配置。日志这里配置了输出到systemd journal。你也可以修改Spring Boot的logback-spring.xml配置将日志文件输出到/opt/jeecg/logs/目录便于用tail、cat或ELK等工具查看。我强烈建议使用文件日志并配置日志滚动RollingFileAppender。保存后启用并启动服务systemctl daemon-reload # 重载systemd配置 systemctl enable jeecg.service # 设置开机自启 systemctl start jeecg.service # 启动服务 systemctl status jeecg.service # 查看服务状态如果状态显示active (running)恭喜你后端服务也启动成功了。现在再次访问http://服务器IP整个Jeecg-boot应用应该可以正常登录和操作了。5. 部署后运维、监控与问题排查部署上线不是终点而是运维的起点。下面是一些确保服务稳定运行的关键操作。5.1 基础运维命令掌握这些命令足以应对日常运维# 查看应用实时日志如果你配置了文件日志 tail -f /opt/jeecg/logs/jeecg.log # 查看systemd管理的服务日志 journalctl -u jeecg.service -f # -f 表示跟踪输出 # 服务管理 systemctl stop jeecg.service # 停止 systemctl start jeecg.service # 启动 systemctl restart jeecg.service # 重启先停后启 systemctl reload jeecg.service # 重载对于Spring Boot通常无效需重启 systemctl status jeecg.service # 状态 # 查看进程和资源占用 ps aux | grep jeecg-boot # 查看Java进程 top -p $(pgrep -f jeecg-boot) # 动态监控该进程资源5.2 常见问题与排查技巧实录即使按照步骤操作也难免会遇到问题。这里记录几个我踩过的坑和排查思路。问题1前端页面白屏浏览器控制台报404或网络错误。排查思路检查Nginx服务systemctl status nginx确认Nginx正在运行。检查静态资源直接在浏览器访问一个静态文件如http://服务器IP/static/js/app.xxx.js。如果404说明Nginx的root目录配置错误或者文件没上传到位。用ls -la /opt/jeecg/frontend/static/检查。检查API代理在浏览器控制台查看具体哪个API请求失败了。然后直接在服务器上用curl测试后端接口curl http://127.0.0.1:8080/jeecg-boot/sys/login假设有个登录接口。如果curl能通但前端不通问题在Nginx代理配置检查location /jeecg-boot的proxy_pass地址和端口。如果curl也不通问题在后端服务。检查后端服务systemctl status jeecg.service和journalctl -u jeecg.service -n 50查看后端日志看是否启动成功是否有数据库连接失败等异常。问题2后端服务启动失败状态为failed。排查思路查看详细日志journalctl -u jeecg.service -xe查看最详细的错误信息。常见原因端口占用Address already in use。Spring Boot默认端口8080可能被其他进程占用。用netstat -tlnp | grep :8080查看修改application-prod.yml中的server.port或停止占用进程。配置文件错误YAML格式错误、数据库连接字符串错误、Redis连接失败。仔细检查/opt/jeecg/config/application-prod.yml的语法和内容。一个技巧可以先在命令行用java -jar ...的方式手动启动看看输出更容易定位问题。内存不足JVM无法分配指定的-Xmx内存。调小-Xmx参数或检查服务器剩余内存free -h。依赖缺失虽然打包成Jar但运行时如果依赖了本地库如某些加密狗驱动可能缺失。检查日志中是否有ClassNotFoundException或NoClassDefFoundError。问题3服务运行一段时间后响应变慢或内存占用过高。排查思路监控JVM使用jstat -gc pid 1000 10查看GC情况。如果Full GC频繁说明可能存在内存泄漏或堆内存设置过小。生成堆转储在jeecg.service的ExecStart行添加JVM参数-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/opt/jeecg/logs/以便在内存溢出时自动生成堆转储文件用MAT等工具分析。检查应用日志是否有大量的异常堆栈特别是数据库查询慢日志如果配置了。检查服务器资源使用top,vmstat 1,iostat -x 1查看CPU、内存、IO瓶颈。问题4如何优雅更新版本标准流程在服务器上将新的Jar包如jeecg-boot-xxx-new.jar上传到/opt/jeecg/app/目录下。修改jeecg.service文件中的ExecStart行指向新的Jar包文件名。执行systemctl daemon-reload。执行systemctl restart jeecg.service。通过systemctl status和查看日志确认新版本启动成功。更稳妥的做法蓝绿/滚动更新思想新旧Jar包使用不同文件名并存。修改jeecg.service指向新文件后daemon-reload。先systemctl stop旧服务再systemctl start新服务。这样回滚极其快速只需改回文件名并重启。永远保留上一个稳定版本的Jar包和配置文件。5.3 安全与优化建议防火墙配置服务器防火墙如firewalld或iptables只开放80HTTP、443HTTPS如果用了SSL和SSH端口。关闭后端应用端口如8080的外部访问只允许本机127.0.0.1访问由Nginx反向代理。firewall-cmd --permanent --add-servicehttp firewall-cmd --permanent --add-servicehttps firewall-cmd --permanent --remove-port8080/tcp # 确保8080不对外开放 firewall-cmd --reload使用非root用户运行在jeecg.service中将Userroot改为一个新建的普通用户如appuser并确保该用户对/opt/jeecg目录有读写权限。这能降低安全风险。配置HTTPS使用Let‘s Encrypt等工具为域名申请免费SSL证书并在Nginx中配置将HTTP重定向到HTTPS。这是生产环境的必备项。日志轮转使用logrotate工具配置对应用日志文件如/opt/jeecg/logs/jeecg.log进行自动切割、压缩和清理防止日志占满磁盘。部署本身是一个系统工程从打包规范到服务器配置再到日常监控每一个环节都影响着服务的稳定性。对于Jeecg-boot这类项目采用Nginx托管前端独立Jar包运行后端systemd管理的混合模式在复杂度和可控性上达到了很好的平衡。记住每次变更前做好备份修改配置后先测试语法重启服务后紧盯日志。这套流程跑顺了再结合Jenkins、Docker热词中的docker安装部署、idea 怎么发布jar到本地的桌面端docker是另一个维度的优化等工具实现自动化你的部署能力就能再上一个台阶。