V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
mythmgn
V2EX  ›  Python

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

  •  
  •   mythmgn · 2019-06-30 22:24:44 +08:00 · 1937 次点击
    这是一个创建于 1958 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1.1 踩坑案例

    长期运行的 daemon 进程或者 socket 测试类进程, 经常遇到的坑是:

    IOError: [Errno 24] Too many open files

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

    1.2 填坑和分析

    一般从两个方面入手:

    1.2.1 从程序优化入手

    • 检查文件打开是否遵循了"谁打开谁关闭"原则
    • 文件是否存在关闭泄露

    a. 谁打开谁关闭是个普适的原则:

    • 只有逻辑设计者自己最熟悉

      • 哪些文件 FD 需要一直维持打开状态
      • 哪些文件直到某个事件发生后关闭
    • 短暂的文件读写打开推荐使用 pythonic 的 with statement

    # 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

    下期坑位预告

    • PyDaemon 进程长什么样

    文章来源

    作者持续更新的 cnblogs: https://www.cnblogs.com/mythmgn/

    作者持续更新的 Github:


    Life is short. We use Python.

    6 条回复    2019-07-01 12:34:47 +08:00
    anonymous256
        1
    anonymous256  
       2019-07-01 00:55:55 +08:00 via Android
    python2.7 告辞
    iwanghang
        2
    iwanghang  
       2019-07-01 01:23:51 +08:00
    不错
    so1n
        3
    so1n  
       2019-07-01 10:38:03 +08:00
    有的还需要编辑 /etc/systemd/system.conf 的 DefaultLimitNOFILE 和 DefaultLimitNPROC,光靠 /etc/security/limits.conf 无法生效
    www5070504
        4
    www5070504  
       2019-07-01 11:13:42 +08:00
    用什么语言 文件描述符泄露都会导致这个问题 这个真不能算是 python 采坑 另外这本身也不算坑
    mythmgn
        5
    mythmgn  
    OP
       2019-07-01 12:33:33 +08:00
    @so1n

    先赞一个.

    是的, 不同发行版配置不一. 我在示例里给了下参考 Centos 6.3. 在文章最后我也提示下大家吧.

    代码示例支持
    平台: Centos 6.3
    Python: 2.7.14
    代码示例: 菜单 - Python 踩坑指南代码示例
    mythmgn
        6
    mythmgn  
    OP
       2019-07-01 12:34:47 +08:00
    @anonymous256 python3 目前在 beta, 近期会发出来除了 网络通信框架 cup.net.async 之外的版本.

    默认 unicode 之后, 对网络包序列化处理上影响多, 这块工作量比想象的大. 哈哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   996 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 19:46 · PVG 03:46 · LAX 11:46 · JFK 14:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.