进程与定时任务
ps、jobs、cron、systemd timer。
进程与定时任务
这一课你将能做到
- 用 ps / top 定位 Java 进程,说清 kill -15 与 kill -9 的区别并正确重启应用
- 用 nohup / & / jobs / fg / bg 管理后台任务,SSH 断开服务不挂
- 编写并调试 crontab 定时任务,实现每天凌晨自动备份 MySQL
为什么要学
Spring Boot 应用在 Linux 上就是一个进程。发布要停旧起新、OOM 要找元凶、日志疯涨要定位写盘的进程——不懂进程管理,你只能对着告警干瞪眼。crontab 则是穷人的调度中心:没上分布式调度平台之前,数据库备份、日志清理、证书续期全靠它。面试里「kill -9 和 kill -15 的区别」「crontab 五个字段」「进程怎么优雅关闭」都是后端高频题,答不好会显得没碰过生产。
人话:进程就是「正在跑的程序」,每个都有身份证号(PID)。kill 不是「杀」而是「发信号」——-15 是敲门说「请收拾东西离开」(应用能执行 shutdown hook、释放连接池),-9 是直接抬走(Spring Boot 的优雅停机、MQTT 消息都来不及处理)。定时任务就是给系统请了个闹钟管家。
先建立图像
进程生命周期与信号路径:
java -jar app.jar
│
▼
内核分配 PID(如 12345)
│
kill -15 12345(SIGTERM,默认) kill -9 12345(SIGKILL)
│ │
JVM 收到信号 → 执行 shutdown hook 内核直接回收,JVM 无感知
优雅停机:停接新请求、处理完存量、 线程当场冻结,可能:
关闭连接池、刷盘、退出 - 数据没刷盘
- 临时文件残留
- 端口 TIME_WAIT 堆积
crontab 五字段口诀:
┌──────── 分 0-59
│ ┌────── 时 0-23
│ │ ┌──── 日 1-31
│ │ │ ┌── 月 1-12
│ │ │ │ ┌ 星期 0-7(0 和 7 都是周日)
│ │ │ │ │
* * * * * 要执行的命令
分 时 日 月 星期
例:0 3 * * * 每天 03:00
例:*/5 * * * * 每 5 分钟
例:0 9 * * 1-5 工作日每天 09:00
跟着做
步骤 1:看进程:ps 的两副面孔
ps -ef | grep java # 风格 1:全格式列表
ps aux | grep mysql # 风格 2:BSD 风格,含 CPU/内存占用
ps -ef | grep [j]ava # 技巧:[j]ava 避免匹配到 grep 自己
pgrep -l java # 只列进程名和 PID,最清爽
pstree -p | head -20 # 进程树,看父子关系
面试常问「ps -ef 和 ps aux 的区别」:内容重叠,-ef 强在完整命令行(看启动参数),aux 强在 %CPU %MEM 排序排查资源大户,ps aux --sort=-%mem | head 直接找内存 Top。
步骤 2:实时观察:top
top # 默认 3 秒刷新,q 退出
# 交互键:P 按 CPU 排序,M 按内存排序,1 展开每核
# 关键行解读:
# %Cpu(s): 12.3 us, 3.1 sy, 80.0 id, 4.0 wa
# us=用户态 sy=内核态 id=空闲 wa=等磁盘(高 wa 先查 IO)
# load average: 0.5, 0.4, 0.3 ← 1/5/15 分钟负载,经验:不超过 CPU 核数
top 是进入服务器的第一眼体检,us 高=应用在算,wa 高=磁盘瓶颈,load 远超核数=过载。
步骤 3:优雅重启一个「应用」
用 sleep 模拟 Java 进程练手,不伤真服务:
mkdir -p ~/proc-lab && cd ~/proc-lab
nohup sleep 300 > sleep.out 2>&1 & # 启动后台进程
echo $! # $! = 最近一个后台进程的 PID
pgrep -l sleep
kill <PID> # 默认就是 -15 优雅终止
pgrep -l sleep || echo "已退出"