Linux下如何优雅终止Java游戏服务器进程?
优雅终止nohup启动的Java游戏服务器并重新关联进程
我之前也碰到过类似的Java服务优雅退出问题,刚好可以给你几个实用的解决方案:
一、先解决优雅终止的核心问题:发送正确的信号
你之前用kill <PID>没触发shutdown hook,大概率是不小心用了kill -9 <PID>(强制杀死信号SIGKILL)——这个信号是操作系统直接终止进程,Java根本没机会执行钩子。正确的做法是发送SIGTERM信号(默认kill命令就是这个,或者明确写kill -15 <PID>),Java会捕获这个信号并触发shutdown hook。
更方便的PID查找方式
不用每次靠top手动找PID,直接用命令精准过滤:
# 匹配你的游戏服务器进程 pgrep -f "com.ruseps.GameServer"
或者给Java进程加个自定义标识参数,启动时改成:
nohup java -Xmx220m -Dserver.name=RSPS -cp bin:lib/* com.ruseps.GameServer &
之后找PID就更简单:
pgrep -f "RSPS"
写个一键停止脚本(推荐)
新建stop.sh,省去每次手动输命令的麻烦:
#!/bin/bash cd "RSPS" # 获取服务器进程PID SERVER_PID=$(pgrep -f "com.ruseps.GameServer") if [ -z "$SERVER_PID" ]; then echo "RSPS服务器当前未运行" exit 1 fi echo "正在优雅停止RSPS服务器(PID: $SERVER_PID)..." # 发送SIGTERM信号触发shutdown hook kill -15 "$SERVER_PID" # 等待进程完全退出(可选,确保数据保存完成) wait "$SERVER_PID" 2>/dev/null echo "RSPS服务器已成功停止"
给脚本加执行权限:chmod +x stop.sh,之后直接运行./stop.sh即可。
二、重新关联后台进程的方法
如果想把已经用nohup启动的后台进程重新关联到当前终端(这样可以直接用Ctrl+C触发SIGINT信号,同样能执行shutdown hook),可以用reptyr工具:
- 先安装reptyr(以Debian/Ubuntu为例):
sudo apt install reptyr
- 用上面的
pgrep命令找到服务器进程的PID - 执行命令关联进程:
reptyr <PID>
关联成功后,你就能在当前终端看到服务器的实时输出,此时按Ctrl+C就能优雅触发shutdown hook了。
三、更省心的长期替代方案:用screen/tmux替代nohup
nohup+tail的组合虽然能用,但screen/tmux能让你更直观地管理后台进程,还能随时重新连接终端:
用screen的步骤:
- 安装screen:
sudo apt install screen
- 创建一个新的专属会话:
screen -S rsesp_server
- 在这个会话里直接运行你的启动命令(不用加nohup和
&):
cd RSPS && echo "Booting the RSPS..." && java -Xmx220m -cp bin:lib/* com.ruseps.GameServer
- 退出会话但保持进程运行:按
Ctrl+A然后按D - 下次登录后重新连接会话:
screen -r rsesp_server
- 要优雅停止服务器,直接在会话里按
Ctrl+C就行,shutdown hook会正常执行。
这样既不用单独看nohup.out日志,又能随时管理进程,比nohup方便很多。
内容的提问来源于stack exchange,提问作者Jaquarh




