You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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会话管理,同时提升应用稳定性:

  1. 在部署服务器创建/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
  1. 修改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
  1. 配置部署用户免密执行systemctl命令(通过sudoers文件设置)。

内容的提问来源于stack exchange,提问作者Ramazan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 06:26:19