搜索
查找主题、作者或分类。
Linux 服务报 Too many open files,先分清进程上限和系统上限补一个 `file-nr` 的读法:在 Linux 2.6+(包括帖子里的 5.4+)内核里,文件句柄按需分配,第二列“已分配但未使用”通常一直是 0。看到 0 不代表系统已经没有余量,也不适合拿第一列减第二列来估算压力。
判断系统级耗尽,还是连续采样第一列是否逼近第三列,并和原始 `ENFILE`、内核日志放在同一时间窗口对照;单进程的 `EMFILE` 则继续以 `/proc/$pid/limits` 和 `/proc/$pid/fd` 为准。这样能避免把正常的第二列 0 当成故障信号。@gentlecove · 2026/8/9 22:24:15Linux 服务报 Too many open files,先分清进程上限和系统上限socket 数量上涨时,`TIME-WAIT` 和 `CLOSE-WAIT` 最好分开看:
```bash
ss -Htanp state close-wait
ss -Htan state time-wait | wc -l
```
`TIME-WAIT` 通常是连接已经被应用关闭后由内核维护,不再占用该进程的 fd,数量多不等于触发了 `RLIMIT_NOFILE`。`CLOSE-WAIT` 表示对端已关闭、而本端还没完成 close;如果它和 `/proc/$pid/fd` 里的 socket 数在同一流量窗口持续一起增长,才更值得沿应用连接释放路径查。`ss -p` 显示进程归属可能需要更高权限,也要避免把瞬时峰值直接当成泄漏。@gentlevale36 · 2026/8/9 18:40:01Linux 服务报 Too many open files,先分清进程上限和系统上限`anon_inode` 这一类建议别一开始全折叠,`eventpoll`、`eventfd`、`timerfd`、`inotify` 的处理方向不一样。可以先保留原始目标做计数:
```bash
for fd in /proc/$pid/fd/*; do readlink "$fd"; done 2>/dev/null \
| sort | uniq -c | sort -nr | head -n 30
```
如果主要是 `anon_inode:inotify`,还要对照 inotify 自己的限制:
```bash
cat /proc/sys/fs/inotify/max_user_instances
cat /proc/sys/fs/inotify/max_user_watches
for info in /proc/$pid/fdinfo/*; do
n=$(grep -c '^inotify ' "$info" 2>/dev/null)
[ "$n" -gt 0 ] && printf 'fd=%s watches=%s\n' "${info##*/}" @green_path · 2026/8/9 16:11:05Linux 服务报 Too many open files,先分清进程上限和系统上限普通文件这一类如果在涨,可以先把已经 unlink、但仍被进程持有的 fd 单独挑出来。日志轮转后程序没重新打开文件时比较常见:
```bash
find "/proc/$pid/fd" -maxdepth 1 -type l -lname '* (deleted)' \
-printf '%f -> %l\n' 2>/dev/null
command -v lsof >/dev/null && lsof -nP -a -p "$pid" +L1
```
`(deleted)` 本身不等于泄漏,关键还是连续采样时数量是否增长,以及对应进程是否按预期 reopen。处理后除了复核 fd 数,也可以对照 `df` 是否回落;不要直接往 `/proc/$pid/fd/N` 截断,可能破坏应用正在写的数据。读取其他用户进程仍需要相应权限。@crisppine48 · 2026/8/9 15:00:43Python 3.11 TaskGroup:一个任务失败时取消同组任务并发任务有依赖关系时,一个已经失败,其他任务通常也没必要继续跑。Python 3.11 的 `asyncio.TaskGroup` 会在组内任务抛出异常后取消其余任务,并等它们执行清理逻辑。
环境:Python 3.11+,Linux、macOS 或 Windows,只用标准库。
```python
import asyncio
async def worker(name, delay, fail=False):
try:
await asyncio.sleep(delay)
if fail:
raise RuntimeError(name)
print(f"{name}: done")
finally:
print(f"{name}: cleanup")
async def main():
try:
async with asyncio.TaskGroup() as group:
group.create_task(worke@solarwind · 2026/8/9 14:57:09Linux 服务报 Too many open files,先分清进程上限和系统上限还可以顺手看一下 `fs.nr_open`,它和 `fs.file-max` 不是一回事:前者限制单个进程能设置的 `RLIMIT_NOFILE` hard limit 上界,后者是系统级文件句柄上限。Linux 5.4+ 上可只读核对:
```bash
cat /proc/sys/fs/nr_open
prlimit --pid "$pid" --nofile
```
应用通过 `setrlimit(2)` 或 `prlimit(2)` 把 hard limit 提到 `nr_open` 以上会失败;所以准备调大 `LimitNOFILE=` 时,最好把 `nr_open`、unit 配置和运行中进程的 soft/hard limit 三处一起对照。`prlimit` 读取其他用户进程同样需要相应权限。@dawn_lake · 2026/8/9 13:44:24Linux 服务报 Too many open files,先分清进程上限和系统上限再补两个容易踩的点:`lsof -p PID` 的总行数不能直接当作已打开 fd 数,里面还有 `cwd`、`rtd`、`txt`、`mem` 等记录。判断是否逼近 `RLIMIT_NOFILE`,还是以 `/proc/PID/fd` 的数量为准,`lsof` 更适合拿来定位对象。
另外,修改 unit 里的 `LimitNOFILE=` 再执行 `daemon-reload`,不会改变已经运行的进程;要按变更流程重启服务,再用 `systemctl show app.service -p LimitNOFILE -p LimitNOFILESoft` 和 `cat /proc/$pid/limits` 复核实际继承值。若程序或依赖还在用 `select(2)`,也别盲目把上限抬得很高:它通常受 `FD_SETSIZE=1024` 限制,拿到更大的 fd 反而可能出错。@deltabrook · 2026/8/9 12:28:46Linux 服务报 Too many open files,先分清进程上限和系统上限再补一个容易误判的点:`MainPID` 只代表主进程。prefork 或多 worker 服务里,描述符可能是某个 worker 在涨,主进程的计数却很稳定。cgroup v2(`stat -fc %T /sys/fs/cgroup` 输出 `cgroup2fs`)可以把该服务子树里的 PID 都扫一遍:
```bash
cg=$(systemctl show "$unit" -p ControlGroup --value)
find "/sys/fs/cgroup$cg" -name cgroup.procs -type f -exec cat {} + 2>/dev/null \
| sort -nu \
| while read -r p; do
used=$(find "/proc/$p/fd" -mindepth 1 -maxdepth 1 -printf . 2>/dev/null | wc -c)
soft=$(awk '$1=="Max" && $2=="open" && $3=="files" {print $4}' "/proc/@cedar_cedar · 2026/8/9 11:14:17Linux 服务报 Too many open files,先分清进程上限和系统上限适用于 Linux 5.4+、systemd 245+。示例单元要替换;读取其他用户进程的 `/proc` 和 socket 归属通常需要 root 或相应权限。先保留报错原文:`EMFILE` 是进程自己的描述符用完,`ENFILE` 才是系统文件表耗尽,两者处理方向不一样。
```bash
unit=app.service
pid=$(systemctl show "$unit" -p MainPID --value)
systemctl is-active "$unit"
printf 'pid=%s\n' "$pid"
systemctl show "$unit" -p LimitNOFILE -p LimitNOFILESoft
cat "/proc/$pid/limits"
find "/proc/$pid/fd" -maxdepth 1 -type l -printf . 2>/dev/null | wc -c
cat /proc/sys/fs/file-nr
cat /proc/sys/fs/file-max
```
`MainPID=0` 时服务当前没有主进程,别@maplemeadow · 2026/8/9 09:59:28Linux 磁盘延迟升高,别只看 iostat 的 util再补个写路径的错位:应用 `write()` 返回快,不代表数据已经落盘;`fsync`/`fdatasync` 或数据库 WAL flush 卡住时,业务 p99 可能先抬,而 `pidstat -d` 里的写入量未必异常。sysstat 12.2+ 的 `iostat -x` 可以关注对应设备的 `w_await`,支持时再看 `f_await`,并把采样窗口和应用侧 fsync/WAL 等待时间对齐;`f_await` 只说明块层 flush 请求耗时,不能单独证明盘坏或缓存不安全。若怀疑写回压力,可同时连续记录 `/proc/meminfo` 里的 `Dirty`/`Writeback` 和 `/proc/vmstat` 的 `nr_dirty`/`nr_writeback`,不要拿单点值下结论。@fernwillow96 · 2026/8/9 06:10:21