幫助解決難以捉摸的文件描述符洩漏
在過去的 6 個月裡,我一直面臨著一個我似乎無法擺脫的問題:顯然是隨機的“打開的文件太多”/“無法打開 TCP/IP 套接字 (24)”/“getaddrinfo: 可以” t 打開文件”我的應用程序日誌中的錯誤。
我按如下方式執行堆棧:mariadb、postgresql、memcached、redis 和 Docker 容器內的幾個基於節點的應用程序、Apache with Passenger 執行 Ruby on Rails(ruby 2.5.5、Rails 6)應用程序和 sidekiq,所有這些都在 CentOS 上7 台機器 (3.10.0-1127.el7.x86_64),具有 6 個核心和 16Gb 的 RAM。在主要工作時間內,負載平均約為 10%,有小峰值,幾乎從未超過 30%。
最初我認為是這個其他 Java 應用程序導致了這個問題,在關閉它之後問題仍然會在更多時間後彈出。
無論我做什麼,我都無法在 CLI 中重現它,它顯然是隨機發生的,機器上沒有任何顯著負載。
服務重啟 1 小時後,我有以下統計資訊:
打開的文件總數
$ lsof | wc -l 30594
打開文件排名靠前的程序
$ lsof | awk '{print $1}' | sort | uniq -c | sort -r -n | head 8260 mysqld 4804 node 2728 Passenger 2491 container 2095 postgres 1445 dockerd 1320 processor 817 php-fpm 720 httpd 709 ruby
Mariadb 變數:
MariaDB [(none)]> Show global variables like 'open_files_limit'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | open_files_limit | 65535 | +------------------+-------+ 1 row in set (0.01 sec) MariaDB [(none)]> Show global status like 'opened_files'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Opened_files | 6151 | +---------------+-------+ 1 row in set (0.00 sec)
我在 sysctl.conf 中將最大打開文件設置為 130k 認為它會解決問題,它只是為我爭取了一些時間,它仍然只是稍後才會彈出
$ sysctl fs.file-nr fs.file-nr = 3360 0 131070
我只是做了一個快速的“ab”測試,打開文件的數量並沒有增加多少:
$ ab -n 1000 -c 10 http://www.example.com/ 9589 mysqld 4804 node 4577 Passenger 3756 httpd 3225 postgres 2491 container 2166 utils.rb: 2080 ruby 1445 dockerd 1364 processor
這可能無關緊要,因為真正的使用者不會重複點擊首頁。
我有一種預感,罪魁禍首可能是 Docker(我在沒有對數據庫進行 docker 化的情況下執行了更繁忙的伺服器),但我寧願在將數據庫移出 Docker 之前調查其他可能性,因為這將是一個非常痛苦的過程。
將不勝感激一些指示
這是因為只有 4096 個 inotify 處理程序。我增加了限制,問題就消失了。
fs.file-max = 131070 fs.inotify.max_user_watches = 65536