[代碼修訂版] 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
# 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 進程長什麼樣

Life is short. We use Python.

点赞

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *