最简单的后台运行(不推荐用于生产环境)
这是最直接的方法,适合临时测试或简单的脚本。

使用 & 符号
在命令行的末尾加上 & 符号,可以让命令在后台异步执行。
nohup java -jar your-app.jar &
nohup: "No Hang Up" 的缩写,它的作用是让程序忽略SIGHUP信号,这个信号通常在终端关闭时由系统发送给终端下的所有进程,使用nohup可以确保即使你关闭了 SSH 终端,程序也会继续运行。&: 将命令放入后台执行。
执行后会发生什么?
- 程序会启动,并立即返回命令提示符,你可以在终端做其他事情。
- 程序的输出(标准输出和标准错误)会被重定向到一个名为
nohup.out的文件中,如果这个文件已存在,新输出会被追加到文件末尾。 - 如果当前用户没有写入权限,输出可能会被重定向到
~/nohup.out。
缺点:
- 管理困难:一旦启动,就很难优雅地停止或重启程序,你需要手动找到进程 ID (
PID),然后用kill命令。 - 输出混乱:所有日志都挤在一个
nohup.out文件里,没有日志级别区分,难以管理。 - 无法随系统启动:需要手动配置开机自启。
使用 screen 或 tmux(推荐用于开发/调试)
screen 和 tmux 是强大的终端复用工具,它们可以创建一个持久的“会话”,你可以在其中运行程序,然后安全地断开 SSH 连接,当你重新连接时,可以“附加”回之前的会话,看到程序的实时输出。

以 screen 为例
-
创建一个新的会话
screen -S my-java-app
这会创建一个名为
my-java-app的新会话,并进入该会话的终端。 -
在会话中启动 Java 程序
java -jar your-app.jar
程序现在就在这个
screen会话中运行了,你可以看到它的实时输出。 -
断开会话 按下
Ctrl + A,然后松开,再按D,你会 detached(分离)会话,但程序在后台继续运行,终端会提示[detached from ...]。 -
重新附加到会话 当你想查看程序状态或输出时,可以执行:
screen -r my-java-app
你会重新看到程序的终端界面。
-
停止程序 附加到会话后,像正常操作一样,按
Ctrl + C终止程序。
优点:
- 交互性强:可以实时查看日志,方便调试。
- 会话持久化:断开 SSH 后程序不受影响。
- 简单易用:基本命令很少,上手快。
缺点:
- 不适合无人值守:如果服务器重启,
screen会话不会自动恢复,需要手动启动。 - 不适合复杂管理:对于需要监控、自动重启、日志轮转等生产级需求,
screen仍然不够。
使用进程管理器(推荐用于生产环境)
这是在 Linux 服务器上运行长期服务的最佳实践,进程管理器可以帮你解决所有后台运行的问题:启动、停止、重启、监控日志、开机自启、资源限制等。
最流行的两个进程管理器是 systemd 和 supervisor。
方案 A: 使用 systemd (现代 Linux 发行版首选)
systemd 是现在绝大多数现代 Linux 发行版(如 Ubuntu 16.04+, CentOS 7+, Debian 8+)的默认系统和服务管理器。
-
创建一个服务单元文件 在
/etc/systemd/system/目录下创建一个文件,my-java-app.service。sudo nano /etc/systemd/system/my-java-app.service
-
编写服务文件内容 将以下内容填入文件,并根据你的实际情况进行修改。
[Unit] Description=My Awesome Java Application # 在网络服务启动后启动,在关机时停止 After=network.target [Service] # 运行程序的用户,建议使用非root用户 User=javauser Group=javauser # Java 程序的启动命令 # 注意:确保 JAVA_HOME 已配置,或者使用完整路径的 java ExecStart=/usr/bin/java -jar /path/to/your-app.jar --spring.profiles.active=prod # 重启策略 # on-failure: 当进程非正常退出时(退出码非0)重启 # always: 总是重启 Restart=on-failure RestartSec=10s # 重启前等待10秒 # 设置工作目录,程序会在此目录下查找配置文件等 WorkingDirectory=/path/to/your-app-dir # 标准输出和标准错误重定向到 journalctl StandardOutput=journal StandardError=journal # 环境变量(可选) Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64" [Install] # 开机自启的级别 WantedBy=multi-user.target
-
管理服务
-
重新加载 systemd 配置
sudo systemctl daemon-reload
-
启动服务
sudo systemctl start my-java-app
-
停止服务
sudo systemctl stop my-java-app
-
重启服务
sudo systemctl restart my-java-app
-
查看服务状态
sudo systemctl status my-java-app
-
设置开机自启
sudo systemctl enable my-java-app
-
禁用开机自启
sudo systemctl disable my-java-app
-
查看日志
systemd的日志集成在journalctl中。# 查看实时日志 sudo journalctl -u my-java-app -f # 查看最近的100行日志 sudo journalctl -u my-java-app --lines 100
-
优点:
- 功能强大:支持启动、停止、重启、依赖管理、资源限制(CPU, 内存)、日志管理等。
- 与系统集成:是操作系统的一部分,开机自启、关机处理非常可靠。
- 标准化:是 Linux 服务的标准管理方式。
方案 B: 使用 supervisor (Python 写的,跨平台)
supervisor 是一个用 Python 写的进程管理工具,非常成熟和稳定,也广泛用于生产环境。
-
安装 supervisor
# Debian/Ubuntu sudo apt-get update sudo apt-get install supervisor # CentOS/RHEL sudo yum install supervisor
-
创建配置文件
supervisor的配置文件通常在/etc/supervisor/conf.d/目录下,创建一个新文件,my-java-app.conf。sudo nano /etc/supervisor/conf.d/my-java-app.conf
-
编写配置文件内容
[program:my-java-app] command=/usr/bin/java -jar /path/to/your-app.jar --spring.profiles.active=prod directory=/path/to/your-app-dir user=javauser autostart=true autorestart=true startsecs=5 stopwaitsecs=10 redirect_stderr=true stdout_logfile=/var/log/supervisor/my-java-app.log
-
管理 supervisor
-
更新配置并启动程序
# 读取所有新配置或修改过的配置文件 sudo supervisorctl update # 启动 my-java-app 程序 sudo supervisorctl start my-java-app
-
停止程序
sudo supervisorctl stop my-java-app
-
重启程序
sudo supervisorctl restart my-java-app
-
查看状态
sudo supervisorctl status
-
查看日志
# 日志文件由配置文件中的 stdout_logfile 指定 tail -f /var/log/supervisor/my-java-app.log # 或者使用 supervisorctl 的 tail 命令 sudo supervisorctl tail my-java-app
-
优点:
- 配置简单:
ini格式的配置文件比systemd的单元文件更直观。 - 跨平台:不仅限于 Linux。
- 功能完善:同样支持自动重启、日志管理等。
总结与推荐
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
nohup & |
极其简单,无需额外工具 | 管理困难,日志混乱,无法自启 | 临时任务、快速测试、调试脚本 |
screen / tmux |
交互性强,可实时查看日志 | 不适合无人值守,管理功能弱 | 开发调试、需要交互式查看输出的后台任务 |
systemd |
功能最强大,与系统集成度高,是现代 Linux 标准 | 配置稍复杂,有学习曲线 | 生产环境、长期运行的服务、需要开机自启的服务 |
supervisor |
配置简单直观,成熟稳定 | 功能略少于 systemd,是第三方工具 |
生产环境、特别是非 systemd 系统或偏好 Python 生态的环境 |
最终建议:
- 对于任何严肃的生产环境部署,请毫不犹豫地选择
systemd,它是目前 Linux 服务的黄金标准,提供了最全面和可靠的保障。 - 对于个人开发或需要频繁交互调试的场景,
screen是一个非常高效和便捷的工具。 - 避免在生产环境中单独使用
nohup &来管理长期服务,除非你非常清楚它的局限性并愿意手动处理所有后续问题。
