进程服务与文件描述符

3 阅读3分钟

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 看出来的。」(把话题引到磁盘题,会更连贯)