如何使用Jenkins在Windows Server上自动化部署Spring Boot应用
Windows Server 2019 下Jenkins Pipeline实现Spring Boot自动启停部署方案
你已经完成JFrog制品拉取到服务器指定目录的步骤,剩下的自动启动环节按以下落地即可,都是生产环境踩过坑验证过的方案,没有Linux教程套Windows的水土不服问题。
前置准备
- 把目标Windows Server 2019配置为Jenkins代理节点:要么直接把Jenkins装在这台服务器上,要么通过Java Web Start方式把服务器挂载为Jenkins agent,给节点打上自定义标签(比如
windows-prod-app),确保流水线步骤可以直接在服务器本地执行,不要用远程命令调用的方式,权限和兼容性坑极多。 - 给Jenkins agent的运行用户配置本地管理员权限,避免后续操作服务、杀进程时出现权限不足的问题。
- 把Spring Boot应用注册为Windows系统服务,不要直接用
java -jar后台跑进程——Jenkins流水线执行结束后会默认清理所有衍生子进程,直接启动的Java进程会被强制杀死,用系统服务托管可以完全和Jenkins进程生命周期解耦,还支持开机自启、异常自动重启。服务包装直接用WinSW即可,是Windows生态下最轻便的服务包装工具,不需要额外依赖。
WinSW服务配置步骤
- 把WinSW执行文件放到你的应用部署目录(比如
C:\deploy\my-springboot-app),重命名为和你的应用匹配的名称,比如app-service.exe - 同目录下新建同名xml配置文件
app-service.xml,参考配置如下:
<service> <id>SpringBootProdApp</id> <name>SpringBoot生产业务服务</name> <description>核心业务Spring Boot应用</description> <executable>java</executable> <arguments>-jar "C:\deploy\my-springboot-app\app.jar" --spring.profiles.active=prod</arguments> <logpath>C:\deploy\my-springboot-app\logs</logpath> <log mode="roll-by-size"> <sizeThreshold>10240</sizeThreshold> <keepFiles>10</keepFiles> </log> <onfailure action="restart" delay="10 sec"/> </service>
- 第一次部署时,用管理员权限打开CMD,执行
C:\deploy\my-springboot-app\app-service.exe install完成服务注册,后续不需要重复执行这个操作。 - 每次从JFrog拉取新的jar包后,统一重命名为固定名称
app.jar覆盖旧包,不需要修改服务配置。
Pipeline流水线核心逻辑
直接用声明式流水线即可,所有命令都是Windows原生批处理,不需要额外装插件,注意Windows环境下执行命令用bat步骤,不要用sh:
pipeline { agent { label 'windows-prod-app' } // 替换成你自己的Windows节点标签 environment { // 以下变量按你的实际配置修改 SERVICE_NAME = 'SpringBootProdApp' // 和WinSW配置里的id保持一致 APP_PORT = '8080' // 应用实际监听的端口 DEPLOY_PATH = 'C:\\deploy\\my-springboot-app' } stages { stage('拉取JFrog制品') { steps { // 这里放你已经实现的JFrog拉包逻辑,拉取完成后将jar包重命名为app.jar覆盖DEPLOY_PATH下的旧包 echo '已完成最新版本jar包拉取,覆盖旧部署包' } } stage('停止旧应用进程') { steps { bat ''' @echo off rem 先判断服务是否处于运行状态,运行中才执行停止,避免命令报错中断流水线 sc query %SERVICE_NAME% | findstr "RUNNING" if %errorlevel% EQU 0 ( net stop %SERVICE_NAME% timeout /t 5 /nobreak > nul ) rem 兜底清理端口占用进程,避免服务退出不彻底导致端口被占 for /f "tokens=5" %%p in ('netstat -ano ^| findstr ":%APP_PORT%" ^| findstr "LISTENING"') do ( taskkill /f /pid %%p ) ''' } } stage('启动新服务并校验可用性') { steps { bat ''' @echo off net start %SERVICE_NAME% rem 轮询检测端口是否正常监听,最多等待30秒,超时直接判定部署失败 set wait_time=0 :check_start timeout /t 3 /nobreak > nul set /a wait_time+=3 netstat -ano | findstr ":%APP_PORT%" | findstr "LISTENING" if %errorlevel% EQU 0 ( echo 服务启动成功,端口%APP_PORT%已正常监听 exit 0 ) if %wait_time% LSS 30 ( goto check_start ) echo 服务启动超时,请检查应用日志排查问题 exit 1 ''' } } } }
常见踩坑说明
- 路径书写:Groovy语法里Windows路径不要直接写单反斜杠,要么用双反斜杠
\\,要么用正斜杠/,否则会被识别为转义字符导致路径错误。 - 不要用任务计划程序或者直接后台启动Java进程的方式托管应用,不仅稳定性差,还会碰到Jenkins子进程清理、用户登录态丢失的问题,系统服务是Windows下最稳的托管方式。
- 启动校验环节不能省,不要执行完
net start就判定部署成功,必须检测端口实际监听状态,避免应用启动失败流水线还显示成功的假绿情况。 - 如果Java环境是自定义安装的,在WinSW配置里把
<executable>的java值改成绝对路径,比如C:\jdk\bin\java.exe,避免服务管理器找不到Java命令。
内容的提问来源于stack exchange,提问作者Vinu Pillai
相关产品推荐
相关产品推荐

