一、什么是 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 的核心优势
- 简单易用,无需复杂配置
- 适合多实例部署
- 完全符合当前项目的部署文档
关键点提醒
- 必须加
&:否则不会后台运行 - 必须重定向日志 :
> trade.log 2>&1 - 停止一定要用 kill:不能直接关闭终端
- 启动后要验证:ps 和 tail 双确认
文档版本:1.0
最后更新:2026-03-22