Bitbucket Pipeline关联Java应用致无限运行问题求助
Bitbucket Pipeline部署Spring Boot应用无限运行问题解决
问题描述
推送代码至master分支时,Bitbucket Pipeline可完成Spring Boot应用的构建与jar包部署,但因关联运行中的Java应用无法脱离会话,导致Pipeline一直无限运行,无法自动结束。
现有配置
bitbucket-pipelines.yml
image: maven:3.8.3-openjdk-11 pipelines: default: - step: name: Build and Deployment caches: - maven script: - echo "Building..." - mvn clean package - echo "Deploying to production" - scp target/app.jar <user>@<hostname>:/home/user/ - pipe: atlassian/ssh-run:0.8.0 variables: SSH_USER: '<user>' SERVER: '<hostname>' COMMAND: '/home/user/run.sh'
run.sh
#!/bin/sh cd /home/user # Specify the name of the Java process PROCESS_NAME="app.jar" # Find the PID of the Java process PID=$(pgrep -f "$PROCESS_NAME") if [ -n "$PID" ]; then echo "Stopping Java process: $PROCESS_NAME (PID: $PID)" kill -15 "$PID" # Wait for the process to terminate while kill -0 "$PID" 2> /dev/null; do sleep 1 done echo "Java process stopped." else echo "Java process $PROCESS_NAME not found." fi # replace jar mv app.jar currently_running_build/ # run app nohup java -jar currently_running_build/app.jar application.yml &
已尝试但无效的方法
- 在shell脚本末尾添加
exit 0 - 使用disown
- 在bitbucket-pipelines中设置
MODE: 'script' - 添加包装shell脚本触发run.sh并脱离
- 将命令设为
nohup /home/user/run.sh &,导致应用停止而非脱离
可行解决建议
1. 彻底隔离Java进程与SSH会话
问题核心是nohup启动的进程仍可能关联SSH会话的标准流,导致Pipeline的SSH连接无法断开。修改run.sh中的启动命令,明确重定向所有流并脱离会话:
# 重定向所有输出到/dev/null,并用disown彻底脱离会话 nohup java -jar currently_running_build/app.jar application.yml > /dev/null 2>&1 & disown $!
2. 改用原生SSH命令替代ssh-run Pipe
Atlassian的ssh-run Pipe默认会保持会话至命令执行完成,改用原生SSH命令并添加-f参数,让SSH在后台执行命令后立即断开连接:
# 替换原pipe步骤为原生ssh命令 - ssh -f <user>@<hostname> '/home/user/run.sh'
注:需提前配置Pipeline与部署服务器的SSH免密登录(将服务器公钥添加至Pipeline密钥管理)。
3. 优化进程停止的精准性
原脚本中pgrep -f "$PROCESS_NAME"可能误匹配含该文件名的无关进程,改用更精准的进程匹配逻辑:
# 仅匹配java -jar启动的目标进程 PID=$(ps aux | grep "java -jar.*$PROCESS_NAME" | grep -v grep | awk '{print $2}')
避免误杀进程导致的阻塞或异常。
4. 使用systemd管理应用(推荐)
将Spring Boot应用注册为systemd服务,完全脱离SSH会话管理,同时提升应用稳定性:
- 在部署服务器创建
/etc/systemd/system/app.service:
[Unit] Description=Spring Boot Application After=network.target [Service] User=user WorkingDirectory=/home/user/currently_running_build ExecStart=/usr/bin/java -jar app.jar application.yml Restart=always [Install] WantedBy=multi-user.target
- 修改
run.sh改用systemd命令:
#!/bin/sh cd /home/user # 停止服务 sudo systemctl stop app.service # 替换jar包 mv app.jar currently_running_build/ # 启动服务 sudo systemctl start app.service
- 配置部署用户免密执行systemctl命令(通过sudoers文件设置)。
内容的提问来源于stack exchange,提问作者Ramazan
相关产品推荐
相关产品推荐

