Python 踩坑之旅进程篇其五打不开的文件

代码示例支持
平台: Centos 6.3
Python: 2.7.14
代码示例: 菜单 - Python踩坑指南代码示例
1.1 踩坑案例
长期运行的daemon进程或者socket测试类进程, 经常遇到的坑是:

IOError: [Errno 24] Too many open files

即进程遇到 IO 错误, 无法打开更多的文件.

1.2 填坑和分析
一般从两个方面入手:

1.2.1 从程序优化入手
检查文件打开是否遵循了"谁打开谁关闭"原则
文件是否存在关闭泄露
a. 谁打开谁关闭是个普适的原则:

只有逻辑设计者自己最熟悉
哪些文件 FD 需要一直维持打开状态
哪些文件直到某个事件发生后关闭
短暂的文件读写打开推荐使用 pythonic 的 with statement

在此推荐小编创建的Python学习交流群:835017344,这里是python学习者聚集地,有大牛答疑,有资源共享!有想学习python编程的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习。

with 语法会在生命周期后自动关闭打开的文件 FD

with open('xxxx_path.file', 'w') as fhandle:
fhandle.dosth()
b. 检查文件 FD 是否存在泄漏

系统设计阶段一般会预估系统总体可打开的 FD 情况. 当出现如下情况时可能出现了泄漏 BUG

外围监控系统发现该进程 FD 大量突破了设计预估
打开 FD 增长趋势异常
一般随着业务增加, FD 会线性增长, 但有限度和规律
如果增长曲线不停的出现陡峭增长且在业务低峰期也如此可能出现了泄露
Python 基础库 CUP 提供对进程打开 FD 的支持, 详见示例代码.

1.2.2 从资源软硬限入手
了解系统的资源软硬限制
检查进程可打开的FD是否突破了系统限制
长期运行的 daemon 进程尤其注意
以 Centos 6.3 Linux系统 为例, 查看 /etc/security/limits.conf 获得系统软硬限资源

  • soft nofile 10240
  • hard nofile 10240
    其中, 用户不能突破系统的硬线 hard nofile limit .

用户也可以通过 shell 命令 ulimit -n 来限定该 shell 启动的所有进程的 nofile

当然非 root 用户是不能突破系统硬线的
用户为了进程控制, 可以设定nofile更小
ulimit -a 可以查看当前用户被设定的限制, 示例:

[test@agent1 ~]$ ulimit -a
core file size (blocks, -c) 0
.......
open files (-n) 10240
.....
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
1.4.1 技术关键字
Open FD
资源 Soft limit / Hard limit

推荐阅读更多精彩内容