Linux 进程管理:从 ps 到 systemd,一次讲清
Linux 进程管理:从 ps 到 systemd,一次讲清
服务器上服务起不来、CPU 被吃满、内存越跑越高,十有八九是进程出了问题。进程管理就四件事:看进程、找问题进程、管进程、让进程开机自启。下面按这个顺序讲清。
一、看进程:ps、top、htop
最常用的是 ps aux,看当前所有进程:
ps aux | head -20
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10
输出里重点看这几列:USER 是谁跑的,%CPU 和 %MEM 是占用,STAT 是状态(R 运行、S 睡眠、D 不可中断睡眠、Z 僵尸),COMMAND 是命令。
想看某个服务相关的进程,用 grep 过滤:
ps aux | grep nginx
ps aux | grep -v grep | grep mysql
top 是实时看,按 M 按内存排序,按 P 按 CPU 排序,按 q 退出:
top
服务器上没装 htop 时,top 够用了。装了 htop 更直观,支持鼠标点选和 F9 杀进程:
htop
只看某个用户的进程:
ps -u www-data
top -u nginx
二、找问题进程:CPU 高、内存高、僵尸进程
CPU 被吃满
先用 top 看是哪个进程占 CPU,再看它是干什么的:
top -b -n 1 | head -20
ps -p <PID> -o pid,ppid,%cpu,%mem,cmd
如果是一个 Java 进程占满 CPU,可以看它里面的线程:
top -H -p <PID>
找到最耗 CPU 的线程号,转成十六进制,再去 jstack 里对:
printf "%x\n" <线程号>
jstack <PID> | grep -A 20 <十六进制线程号>
内存越跑越高
看进程内存占用和系统剩余内存:
free -h
ps aux --sort=-%mem | head -10
cat /proc/<PID>/status | grep -E 'VmRSS|VmSize'
注意区分:free 里 buff/cache 是系统拿去做缓存的内存,不算真正被用掉,available 那一列才是真正能用的。
僵尸进程
STAT 是 Z 的就是僵尸进程,本身不占资源,但占进程号。僵尸进程是子进程死了、父进程没回收造成的,杀僵尸进程没用,要处理它的父进程:
ps aux | grep Z
ps -o pid,ppid,stat,cmd -p <僵尸进程PID>
找到父进程 PID 后,重启父进程,或者给父进程发信号让它回收子进程。
D 状态进程
STAT 是 D 的进程在等磁盘 IO,杀不掉,只能等 IO 完成或者解决磁盘问题。D 状态一大片,往往是磁盘满了或者磁盘坏了,先去查磁盘。
三、管进程:kill、pkill、nice
结束进程
先礼后兵。默认的 TERM 信号(15)让进程自己收拾完再退出:
kill <PID>
等几秒还没死,再用 KILL 信号(9)强制杀:
kill -9 <PID>
KILL 是最后手段,数据可能来不及落盘,能不用就不用。
按名字杀一批:
pkill -f "python app.py"
killall nginx
pkill 的 -f 是按完整命令行匹配,写错了容易误杀,执行前先用 pgrep 核对:
pgrep -af "python app.py"
调整优先级
nice 值越小优先级越高,范围 -20 到 19。启动时指定:
nice -n 10 python app.py
对已经在跑的进程改优先级:
renice -n 5 -p <PID>
普通用户只能把 nice 值调大(降低优先级),调小需要 root。
后台运行
让进程在后台跑,关掉终端也不死:
nohup python app.py > app.log 2>&1 &
看后台任务:
jobs
把后台任务拉回前台:
fg %1
临时跑个长任务,screen 或 tmux 更稳,断线重连后还能接回来。
四、让进程开机自启:systemd
现在主流发行版都用 systemd 管服务。写一个 service 文件:
vim /etc/systemd/system/myapp.service
内容示例:
[Unit]
Description=My App
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 /opt/myapp/app.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
写好后重载配置、启动、设开机自启:
systemctl daemon-reload
systemctl start myapp
systemctl enable myapp
systemctl status myapp
常用操作就这几个:
systemctl start myapp
systemctl stop myapp
systemctl restart myapp
systemctl status myapp
systemctl is-enabled myapp
服务起不来,先看状态和日志:
systemctl status myapp
journalctl -u myapp -n 50
journalctl -u myapp --since "10 minutes ago"
Restart=on-failure 的意思是进程异常退出后自动重启,配合 RestartSec=5 等 5 秒再拉起来,大多数线上服务都这么配。
五、排查流程:一个例子
线上接口突然变慢,按这个顺序查:
top
ps aux --sort=-%cpu | head -10
free -h
df -h
ss -tlnp
systemctl status myapp
journalctl -u myapp -n 100
top 先看是谁占 CPU,free 和 df 排除内存和磁盘,ss 看端口还在不在监听,systemctl 和 journalctl 看服务本身的状态和报错。大多数问题走到这一步就有答案了。
六、常用命令速查
查看进程:ps aux、top、htop、pgrep -af 关键词
结束进程:kill PID、kill -9 PID、pkill -f 关键词
调优先级:nice -n 10 命令、renice -n 5 -p PID
后台运行:nohup 命令 > 日志 2>&1 &、jobs、fg %1
服务管理:systemctl start/stop/restart/status 服务名、systemctl enable 服务名
服务日志:journalctl -u 服务名 -n 50、journalctl -u 服务名 --since "10 minutes ago"
记住一个原则:杀进程之前先确认它是谁,ps -p PID -o pid,ppid,cmd 看一眼再动手,生产环境误杀一个关键进程,代价比慢几分钟大得多。
- 点赞
- 收藏
- 关注作者
评论(0)