题目一:进程有哪几种状态(生命周期)?
平时学的是五种状态:新建、就绪、运行、阻塞、终止。但在 Linux 里能查看到的更加详细,下面命令的 STAT 列就展示了进程状态:
$ ps -aux
状态有很多种,看首字母即可,其余不必太在意:
- R:运行(Running)
- S:可中断睡眠(Sleep)
- D:不可中断睡眠(通常是 I/O)
- T:停止的进程
- Z:僵尸进程
- X:死掉的进程
题目二:通过 ps 命令可以获取哪些关键信息?
ps 命令一般用来查 PID,之后可以通过 kill 干掉进程,或者通过 PID 读取 /proc 目录获取进程监控信息。和 top 一样,用 ps -aux 参数可以看到进程的各种指标:
| 字段 | 含义 |
|---|---|
USER |
运行进程的用户 |
PID |
进程 ID |
%CPU |
CPU 占用率 |
%MEM |
内存占用率 |
VSZ |
占用的虚拟内存 |
RSS |
占用的实际(驻留)内存 |
TTY |
进程运行的终端 |
STAT |
进程状态(见 man ps 的 /STATE) |
STARTED |
启动日期 |
TIME |
运行时间 |
COMMAND |
启动命令 |
如果只是想查看 PID,可以直接用 pgrep:
$ pgrep sshd
10180
题目三:top 命令怎么按 cpu、mem 排序?还能获取哪些信息?
用 uptime 可以查看机器负载情况:
$ uptime
21:31 up 4 days, 6:54, 3 users, load averages: 3.54 3.27 3.02
用 top 可以临时查看进程的实时使用情况:
# 指定刷新时间间隔
$ top -d 1
# 查看指定进程的动态信息
$ top -p 10126
$ top -p 10126,1
# 查看指定用户的进程
$ top -u apache
# 将两次刷新写入文件中
$ top -d 1 -b -n 2 > top.txt
在 top 交互界面中,常用快捷键如下:
| 按键 | 作用 |
|---|---|
M |
按内存使用排序 |
P |
按 CPU 使用排序 |
N |
按 PID 大小排序 |
R |
反转排序 |
f |
自定义显示字段 |
1 |
显示所有 CPU 的负载 |
z |
彩色显示 |
W |
保存 top 环境设置到 ~/.toprc |
当然,top 适合临时查看某台机器的某个进程,但无法查看趋势,也无法批量查看多台服务器。这种情况推荐使用开源监控组件把服务器监控起来。
题目四:怎么让进程在后台运行?怎么切换到前台?
这一题讲的是作业控制(job),通过它可以灵活地让进程在前后台切换、暂停。这里用 sleep 命令举例——sleep 就是运行一个进程、等待一段时间,用来测试前后台切换再合适不过。
先了解前后台的概念:前台运行一个进程会等待交互、卡住命令行终端,除非用 Ctrl+C 终止或 Ctrl+Z 暂停:
$ sleep 5
# 光标在此闪烁,5 秒之内什么也干不了
# 用 Ctrl+C 会终止进程,打印一个 ^C
$ sleep 5
^C
# 用 Ctrl+Z 会暂停进程
$ sleep 5
^Z
[1]+ Stopped sleep 5
暂停的进程用第一题的 ps 命令查看,状态是 T:
$ ps -aux | grep sleep
root 29196 0.0 0.0 10795 2356 pts/0 T 21:45 0:00 sleep 5
用 jobs 命令也可以看到后台进程情况(暂停也相当于切换到后台运行了):
$ jobs
[1]+ Stopped sleep 5
可以看到 [1] 表示它的作业号是 1。尝试把它调到前台运行,会卡在那里直到运行完:
$ fg %1
sleep 5
要让一个进程直接在后台运行,只需在命令结尾加一个 & 符号:
$ sleep 100 &
[1] 29932
$ jobs
[1]+ Running sleep 100 &
要暂停后台运行的进程,得先调到前台,再用 Ctrl+Z:
$ fg %1
sleep 100
^Z
[1]+ Stopped sleep 100
$ jobs
[1]+ Stopped sleep 100
让暂停的进程直接切换到后台运行:
$ bg %1
[1]+ sleep 100 &
$ jobs
[1]+ Running sleep 100 &
注意:以前用 curl 时容易忘记给 URL 加引号。如果是 GET 请求且带参数,一般是下面这种形式——参数分隔符 & 会被误认为是后台执行符号:
http://127.0.0.1/query?name=coding3min&passwd=abc
最后,进程管理中如何干掉一个进程就不必多说了——可以发送信号,也可以直接 kill,最好是通过守护进程来管理。
拓展知识点:守护进程
最不想遇到的事就是进程挂掉——一个告警电话打过来,半夜爬起来手动启动进程。所以进程自动拉起很重要。
常用的方案有:systemctl、supervisorctl,或者自己写 crontab 定时任务,也可以上 k8s、或简单点的 docker-compose。k8s 不仅支持进程自动拉起,还能维护多副本——配置好副本数,挂掉一个会自动恢复;其中的 HPA 支持弹性伸缩,可以根据进程占用情况自动增减副本数量。
如果想让守护进程”耍流氓”、怎么杀都杀不掉,可以做成进程互相拉起——比如 360-A 进程挂了,360-B 进程把它拉起来;360-B 挂了,360-A 再把它拉起来(对,这里就是在调侃 360)。