1:什么是僵尸进程?怎么处理?
考察点:进程回收机制 · 出现率极高
| 问题 | 答案 |
|---|---|
| 什么是僵尸进程 | 子进程已经结束,但父进程没有回收它,进程表项还留着(状态 Z) |
| 怎么处理 | 杀它的父进程(僵尸本身已经死了,kill 它没用) |
| 怎么找出来 | ps aux | grep Z 或 ps -eo stat,pid,comm | grep '^Z' |
原理:
子进程退出时会变成僵尸,等父进程调用 wait() 来"收尸"。
父进程如果一直不 wait(),僵尸就一直挂着,占用进程表项(占 PID,不占内存和 CPU)。
如果父进程也异常退出了,僵尸会被 PID 1 收养并自动回收。
和孤儿进程区分:
| 僵尸进程 | 孤儿进程 | |
|---|---|---|
| 谁没了 | 子进程已退出,父进程还在但不回收 | 父进程先退出,子进程还在跑 |
| 处理 | 杀父进程 | 不需要处理,会被 PID 1 收养并在退出时回收 |
2:怎么自己写一个 systemd 服务?服务文件放哪?
考察点:systemd 单元 · 有没有自己部署过服务
| 目录 | 用途 |
|---|---|
/usr/lib/systemd/system/ | 软件包安装的(别改,升级会被覆盖) |
/etc/systemd/system/ | 管理员自建的,优先级最高 |
/run/systemd/system/ | 运行时生成的 |
一个最小可用的 unit:
[Unit]
Description=My App
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/app --config /etc/app.conf
Restart=on-failure
User=app
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
systemctl daemon-reload # 改完 unit 必须重新加载
systemctl enable --now myapp # 开机自启 + 现在启动
关键字段答法:
[Unit]写Description、After;[Service]写Type、ExecStart、Restart、User、LimitNOFILE;[Install]写WantedBy。写完必须daemon-reload,否则 systemd 看不到。
3:什么是文件描述符?报 Too many open files 怎么查?
考察点:fd 概念 · 连接泄漏 · systemd 的坑
文件描述符(fd)= 进程打开文件/连接的"编号"
· 每打开一个文件、建立一条网络连接,都会占用一个 fd
· Linux 规定:fd 0 是标准输入、1 是标准输出、2 是标准错误
排查四步(★ 会这个就够):
# 1) 看进程当前用了多少 fd
ls /proc/<PID>/fd | wc -l
# 2) 看这个进程的限制是多少
cat /proc/<PID>/limits | grep -i "open files"
# 3) 看具体打开的是什么(是不是连接泄漏)
lsof -p <PID> | head -20
# 4) 处理方式
# · 数量正常但限制太小 → 调大限制
# · 数量持续增长不回落 → 是应用没关连接(代码问题)
怎么调大限制(★ 记住这个坑):
| 方式 | 说明 |
|---|---|
| 临时 | ulimit -n 65535(只对当前会话生效) |
| 对登录用户永久 | 改 /etc/security/limits.conf |
| 对 systemd 服务 | 不读 limits.conf!要改 unit 文件的 LimitNOFILE=65535,然后 systemctl daemon-reload && systemctl restart 服务 |
注意:「改完
limits.conf发现服务还是报Too many open files,是因为 systemd 服务不读limits.conf,要在 unit 里设LimitNOFILE。」
4:怎么查看一个进程打开了哪些文件、端口、线程?
考察点:进程取证工具链 · 排障基本功
| 想看什么 | 命令 |
|---|---|
| 打开了哪些文件 / 端口 | lsof -p PID |
| fd 数量 | ls /proc/PID/fd | wc -l |
| 网络连接 | ss -tanp | grep PID |
| 线程 | ps -L -p PID 或 top -H -p PID |
| 进程的映射内存 | cat /proc/PID/maps、pmap -x PID |
| 进程的启动参数 | cat /proc/PID/cmdline、ps -ef | grep PID |
| 进程的工作目录 | ls -l /proc/PID/cwd |
| 进程的环境变量 | cat /proc/PID/environ |
加分:「排查的时候我习惯直接进
/proc/<PID>/,里面几乎什么都有 —— fd、limits、maps、cmdline、cwd。文件被删了但空间没释放,就是靠lsof | grep deleted看出来的。」(把话题引到磁盘题,会更连贯)