Nohup 使用技术文档

一、什么是 Nohup?

1.1 基本概念

nohup 是 Linux/Unix 系统下的一个命令,用于在用户退出终端会话后让进程继续运行。

1.2 为什么需要 Nohup?

  • 默认情况下,当你关闭 SSH 终端时,所有启动的程序都会被终止
  • nohup 可以忽略挂断信号(SIGHUP),让程序在后台持续运行
  • 结合 & 使用,实现真正的后台运行

二、贸易项目部署现状

2.1 三个独立服务

环境 部署路径 端口 用途
测试版 /home/linaro/server/ 8080 开发自测,随时部署
正式版 /home/trade/server/ 8081 生产环境,每晚9点部署
手机端 /home/mobil/server/ - 移动端服务

三、Nohup 基础命令

3.1 基本语法

复制代码
nohup 命令 [参数] > 日志文件 2>&1 &

3.2 贸易项目标准启动命令

复制代码
# 测试版
nohup java -Dloader.path=/home/linaro/server/lib/ -jar /home/linaro/server/trade-0.0.1.jar > trade.log 2>&1 &

# 正式版
nohup java -Dloader.path=/home/trade/server/lib/ -jar /home/trade/server/trade-0.0.1.jar > trade.log 2>&1 &

# 手机端
nohup java -Dloader.path=/home/mobil/server/lib/ -jar /home/mobil/server/trade-0.0.1.jar > trade.log 2>&1 &

3.3 命令参数详解

参数 说明
nohup 忽略挂断信号,退出终端后继续运行
-Dloader.path 指定依赖库路径
-jar 运行可执行 jar 包
> trade.log 将标准输出重定向到文件
2>&1 将错误输出也重定向到同一个文件
& 放到后台运行

四、完整部署流程(测试版示例)

4.1 本地打包

复制代码
# 进入项目目录
cd /path/to/your/project

# 修改配置文件 application-dev.yml
# 端口: 8080
# 数据库: tradepro

# 清理并打包(跳过测试)
mvn clean package -DskipTests

4.2 上传到服务器

使用 Finalshell 或 scp 命令:

复制代码
# 本地执行
scp target/trade-0.0.1.jar root@你的服务器IP:/home/linaro/server/

4.3 服务器操作

步骤1:查看当前进程

复制代码
ps -ef | grep java
# 或更精确的查找
ps aux | grep "/home/linaro/server/trade-0.0.1.jar"

步骤2:停止旧进程

复制代码
# 方法1:根据PID手动杀死
kill -9 PID

# 方法2:一键杀死(推荐)
ps aux | grep "/home/linaro/server/trade-0.0.1.jar" | grep -v grep | awk '{print $2}' | xargs -r kill -9

步骤3:确认进程已停止

复制代码
ps aux | grep "/home/linaro/server/trade-0.0.1.jar"
# 应该只显示 grep 命令本身

步骤4:启动新版本

复制代码
cd /home/linaro/server/
nohup java -Dloader.path=./lib/ -jar trade-0.0.1.jar > trade.log 2>&1 &

步骤5:验证启动成功

复制代码
# 查看进程
ps -ef | grep linaro/server

# 查看日志
tail -f trade.log
# 应该看到 "Started Application in X seconds"

五、进程管理命令大全

5.1 查看进程

复制代码
# 查看所有 Java 进程
ps -ef | grep java

# 查看特定路径的进程
ps aux | grep "/home/linaro/server/trade-0.0.1.jar"

# 显示进程树
pstree -p | grep java

# 查看端口占用(如果知道端口)
netstat -tlnp | grep 8080

5.2 停止进程

复制代码
# 温和停止(推荐)
kill PID

# 强制停止(当温和停止无效时)
kill -9 PID

# 批量停止同一路径的所有进程
pkill -f "/home/linaro/server/trade-0.0.1.jar"

# 或使用文档中的一键命令
ps aux | grep "/home/linaro/server/trade-0.0.1.jar" | grep -v grep | awk '{print $2}' | xargs -r kill -9

5.3 查看日志

复制代码
# 实时查看日志
tail -f /home/linaro/server/trade.log

# 查看最后100行
tail -100 /home/linaro/server/trade.log

# 搜索日志中的错误
grep ERROR /home/linaro/server/trade.log

# 按时间查看
sed -n '/2026-03-20 10:00/,/2026-03-20 11:00/p' trade.log

六、一键部署脚本

6.1 测试版部署脚本

创建 /home/linaro/server/deploy.sh

复制代码
#!/bin/bash

APP_DIR="/home/linaro/server"
JAR_NAME="trade-0.0.1.jar"
LOG_FILE="$APP_DIR/trade.log"
BACKUP_DIR="$APP_DIR/backup"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

echo -e "${YELLOW}========== 开始部署测试版 ==========${NC}"

# 创建备份目录
mkdir -p $BACKUP_DIR

# 进入应用目录
cd $APP_DIR

# 1. 停止旧进程
echo -e "1. 正在停止旧进程..."
OLD_PID=$(pgrep -f "$JAR_NAME.*$APP_DIR")
if [ ! -z "$OLD_PID" ]; then
    echo "找到进程 PID: $OLD_PID"
    kill -9 $OLD_PID
    sleep 3
    echo -e "${GREEN}✓ 旧进程已停止${NC}"
else
    echo -e "没有找到运行中的进程"
fi

# 2. 备份旧版本
echo -e "2. 备份旧版本..."
if [ -f "$APP_DIR/$JAR_NAME" ]; then
    cp $APP_DIR/$JAR_NAME $BACKUP_DIR/$JAR_NAME.$(date +%Y%m%d_%H%M%S)
    echo -e "${GREEN}✓ 备份完成${NC}"
fi

# 3. 等待上传新版本
echo -e "3. ${YELLOW}请上传新版本到 $APP_DIR 目录${NC}"
echo "上传完成后按任意键继续..."
read -n 1

# 4. 备份旧日志
echo -e "\n4. 备份旧日志..."
if [ -f "$LOG_FILE" ]; then
    mv $LOG_FILE $LOG_FILE.$(date +%Y%m%d_%H%M%S)
    echo -e "${GREEN}✓ 日志已备份${NC}"
fi

# 5. 启动新版本
echo -e "5. 启动新版本..."
nohup java -Dloader.path=$APP_DIR/lib/ -jar $APP_DIR/$JAR_NAME > $LOG_FILE 2>&1 &
sleep 5

# 6. 验证启动
echo -e "6. 验证启动状态..."
NEW_PID=$(pgrep -f "$JAR_NAME.*$APP_DIR")
if [ ! -z "$NEW_PID" ]; then
    echo -e "${GREEN}✓ 启动成功!新进程 PID: $NEW_PID${NC}"
else
    echo -e "${RED}✗ 启动失败,检查日志${NC}"
    tail -n 20 $LOG_FILE
    exit 1
fi

# 7. 显示日志
echo -e "7. 最新日志:"
tail -n 10 $LOG_FILE

echo -e "${GREEN}========== 部署完成 ==========${NC}"
echo "查看实时日志: tail -f $LOG_FILE"

# 添加执行权限
chmod +x /home/linaro/server/deploy.sh

6.2 正式版部署脚本

复制代码
创建 /home/trade/server/deploy.sh(类似,路径改为 /home/trade/server/)

七、常见问题排查

7.1 启动失败

复制代码
# 查看详细错误
tail -200 /home/linaro/server/trade.log

# 常见错误:
# - 端口被占用:netstat -tlnp | grep 8080
# - 内存不足:free -h
# - 权限问题:ls -la /home/linaro/server/

7.2 进程杀不死

复制代码
# 强制杀死所有相关进程
pkill -9 -f "trade-0.0.1.jar"

# 查看进程状态
ps aux | grep defunct  # 查看僵尸进程

7.3 日志不输出

复制代码
# 检查重定向是否正确
ls -la trade.log
cat trade.log

# 直接运行(不用 nohup)测试
java -Dloader.path=./lib/ -jar trade-0.0.1.jar

7.4 内存占用过高

复制代码
# 查看内存使用
top -p PID

# 启动时限制内存
nohup java -Xms256m -Xmx512m -Dloader.path=./lib/ -jar trade-0.0.1.jar > trade.log 2>&1 &

八、最佳实践建议

8.1 日常操作流程

复制代码
# 1. 本地打包
mvn clean package -DskipTests

# 2. 上传到服务器
scp target/trade-0.0.1.jar root@服务器IP:/home/linaro/server/

# 3. SSH登录服务器并执行
cd /home/linaro/server/
./deploy.sh

8.2 创建命令别名

~/.bashrc 中添加:

复制代码
alias psjava='ps -ef | grep java'
alias tailtrade='tail -f /home/linaro/server/trade.log'
alias killtrade='ps aux | grep "/home/linaro/server/trade-0.0.1.jar" | grep -v grep | awk "{print \$2}" | xargs -r kill -9'

8.3 定时任务(正式版每晚9点部署)

复制代码
# 编辑 crontab
crontab -e

# 添加定时任务
59 20 * * * /home/trade/server/deploy.sh >> /home/trade/server/cron.log 2>&1

九、三个环境的快速命令

操作 测试版 (linaro) 正式版 (trade) 手机端 (mobil)
查看进程 `ps aux grep linaro` `ps aux
停止进程 pkill -f "/home/linaro/server/trade" pkill -f "/home/trade/server/trade" pkill -f "/home/mobil/server/trade"
启动命令 cd /home/linaro/server && nohup java -Dloader.path=./lib/ -jar trade-0.0.1.jar > trade.log 2>&1 & cd /home/trade/server && nohup java -Dloader.path=./lib/ -jar trade-0.0.1.jar > trade.log 2>&1 & cd /home/mobil/server && nohup java -Dloader.path=./lib/ -jar trade-0.0.1.jar > trade.log 2>&1 &
查看日志 tail -f /home/linaro/server/trade.log tail -f /home/trade/server/trade.log tail -f /home/mobil/server/trade.log

十、总结

Nohup 的核心优势

  • 简单易用,无需复杂配置
  • 适合多实例部署
  • 完全符合当前项目的部署文档

关键点提醒

  1. 必须加 &:否则不会后台运行
  2. 必须重定向日志> trade.log 2>&1
  3. 停止一定要用 kill:不能直接关闭终端
  4. 启动后要验证:ps 和 tail 双确认

文档版本:1.0

最后更新:2026-03-22

相关推荐
cccyi71 小时前
支持 HTTP 协议的主从 Reactor 高性能服务器组件
服务器·http·reactor
Sakuyu434682 小时前
zabbix源码安装
linux·运维·zabbix
赖亦无2 小时前
【水动力学】06 Linux + Conda 环境下源码编译安装 pypims (CUDA加速) 避坑指南
linux·运维·conda·pypims·水动力学
穷人小水滴2 小时前
使用 WebRTC 实现局域网投屏: PC (GNOME ArchLinux) -> 平板 (Android)
android·linux·webrtc·浏览器·js·gnome·投屏
恋红尘2 小时前
K8S 控制器-资源调度-叩丁狼
linux·docker·kubernetes
weixin_537590452 小时前
《C程序设计语言》练习答案(练习1-7)
linux·c语言·算法
123过去4 小时前
ike-scan使用教程
linux·测试工具
疯狂吧小飞牛10 小时前
GPG基础指令
linux·服务器·网络
C++ 老炮儿的技术栈10 小时前
volatile使用场景
linux·服务器·c语言·开发语言·c++