php-fpm memory leak 問題

2024-10-17

檢查 php-fpm 記憶體使用狀況

列出前 20 名耗用記憶體的程式:

針對第四欄 %MEM

root@linux # ps auxw|head -1;ps auxw|sort -rn -k4|head -20
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mysql     3131  6.5 28.9 14345772 9443540 ?    Ssl   2023 43123:07 /usr/libexec/mysqld --basedir=/usr
apache   31255  2.7  4.8 5612924 1574440 ?     S    07:07   1:13 php-fpm: pool www
apache   32520  5.5  4.5 5637016 1474820 ?     S    07:23   1:38 php-fpm: pool www
apache   32438  3.5  4.5 5604968 1466688 ?     S    07:22   1:06 php-fpm: pool www
apache   32314  1.7  4.5 5599032 1486664 ?     S    07:21   0:33 php-fpm: pool www
apache   31253  3.9  4.4 5600980 1458840 ?     S    07:07   1:47 php-fpm: pool www
apache   31843  4.1  4.3 5598816 1412944 ?     S    07:16   1:31 php-fpm: pool www
apache   31303  6.5  4.3 5610804 1410056 ?     S    07:08   2:55 php-fpm: pool www
apache   31393  1.1  4.2 5245564 1397644 ?     S    07:09   0:30 php-fpm: pool www
apache   31224  7.3  4.2 5233776 1372984 ?     S    07:07   3:21 php-fpm: pool www
apache   32545  5.5  4.0 5611312 1317548 ?     S    07:23   1:36 php-fpm: pool www
apache   32527  4.8  4.0 5621396 1307124 ?     R    07:23   1:25 php-fpm: pool www
apache   32505  4.3  4.0 5604880 1333072 ?     S    07:23   1:16 php-fpm: pool www
apache   32503  3.7  4.0 5607168 1313580 ?     S    07:23   1:06 php-fpm: pool www
apache   31434  2.9  4.0 5244716 1311764 ?     S    07:10   1:15 php-fpm: pool www
apache    1535 10.2  3.9 5633084 1289360 ?     R    07:34   1:52 php-fpm: pool www
apache   32592  9.7  3.8 5597456 1270360 ?     S    07:24   2:46 php-fpm: pool www
apache   32574  9.0  3.7 5237700 1226796 ?     S    07:24   2:35 php-fpm: pool www
apache   32567  3.9  3.7 5242108 1220988 ?     S    07:24   1:08 php-fpm: pool www
apache     863 10.0  3.6 5243820 1199404 ?     S    07:31   2:09 php-fpm: pool www
root@linux # top

top - 07:51:39 up 459 days,  8:06,  1 user,  load average: 7.77, 6.27, 4.45
Tasks: 206 total,   7 running, 127 sleeping,   0 stopped,   0 zombie
%Cpu(s): 43.1 us,  6.4 sy,  0.0 ni, 24.2 id, 16.5 wa,  0.0 hi,  1.1 si,  8.6 st
KiB Mem : 32577108 total,   298452 free, 11612312 used, 20666344 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 16598352 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
  863 apache    20   0 5266052   1.2g   1.1g R  92.0  3.7   1:46.78 php-fpm
  619 apache    20   0 5254932   1.1g   1.0g R  84.3  3.4   1:06.67 php-fpm
32503 apache    20   0 5626068   1.2g   1.2g R  66.0  4.0   0:57.38 php-fpm
 3131 mysql     20   0   13.7g   9.0g  11944 S  41.3 29.0  43122:32 mysqld
  953 apache    20   0 5605044   1.1g   1.0g S  28.3  3.4   1:52.94 php-fpm
  884 apache    20   0 5614556   1.1g   1.0g R  19.3  3.5   2:04.48 php-fpm
32505 apache    20   0 5621264   1.3g   1.2g S  15.3  4.1   1:12.52 php-fpm
32537 apache    20   0 5610024   1.1g   1.1g S   7.7  3.7   2:20.79 php-fpm
32545 apache    20   0 5603120   1.2g   1.2g S   7.7  3.9   1:35.44 php-fpm
  988 apache    20   0 4682532  62460   9036 S   7.0  0.2   0:09.81 httpd
32438 apache    20   0 5611112   1.4g   1.3g S   7.0  4.4   1:04.86 php-fpm
 2741 apache    20   0 5593360 479168 447236 S   4.3  1.5   0:03.06 php-fpm
32520 apache    20   0 5628824   1.3g   1.3g S   4.3  4.3   1:36.79 php-fpm
31843 apache    20   0 5592672   1.3g   1.3g S   4.0  4.3   1:29.78 php-fpm
 1500 apache    20   0 5239952   1.1g   1.0g S   3.7  3.5   0:13.62 php-fpm
31434 apache    20   0 5226144   1.2g   1.2g R   0.7  4.0   1:06.82 php-fpm
32211 apache    20   0 4879140  69164   9036 S   0.7  0.2   0:15.23 httpd
32320 apache    20   0 4485988  60528   9032 S   0.7  0.2   0:13.47 httpd
32760 apache    20   0 4748068  60620   9036 S   0.7  0.2   0:13.79 httpd
 2786 apache    20   0 5248472 528236 483224 S   0.3  1.6   0:36.95 php-fpm
 3775 root       0 -20       0      0      0 I   0.3  0.0   1:45.76 kworker/7:1H
31393 apache    20   0 5220988   1.3g   1.3g S   0.3  4.1   0:28.15 php-fpm

由 PHP FPM status 頁面查詢

輸入網址

http://SERVER_IP/fpm_status123?full

可以看到如下訊息:

pool:                 www
process manager:      dynamic
start time:           20/Aug/2024:02:02:02 +0800
start since:          42434
accepted conn:        37857
listen queue:         0
max listen queue:     0
listen queue len:     0
idle processes:       19
active processes:     1
total processes:      20
max active processes: 25
max children reached: 0
slow requests:        0

************************
pid:                  6447
state:                Idle
start time:           20/Aug/2024:13:29:49 +0800
start since:          1167
requests:             74         注意這個數字
request duration:     261851
request method:       POST
request URI:          /wp-admin/admin-ajax.php
content length:       96
user:                 -
script:               /var/www/html/wp-admin/admin-ajax.php
last request cpu:     38.19
last request memory:  2097152

************************
pid:                  6737
state:                Idle
start time:           20/Aug/2024:13:43:30 +0800
start since:          346
requests:             16     
request duration:     85831
request method:       GET
request URI:          /index.php
content length:       0
user:                 -
script:               /var/www/html/index.php
last request cpu:     81.56
last request memory:  29704192    相當於28MB

************************
pid:                  8154
state:                Running
start time:           20/Aug/2024:13:43:30 +0800
start since:          346
requests:             10
request duration:     275
request method:       GET
request URI:          /fpm_status?full
content length:       0
user:                 -
script:               -
last request cpu:     0.00
last request memory:  0
::
::

解釋
pid                  - the PID of the process;
state                - the state of the process (Idle, Running, ...);
start time           - the date and time the process has started;
start since          - 此 process 已經活了多久秒數
requests             - 這個process 已經處理多少 request 數目
                       當達到 pm.max_requests 數字時 就會關閉此porcess
request duration     - 執行此 request (也就是執行此 php) 花費多久時間 (單位 µs 百萬分一秒)
                       這數字若太大(如超過1秒),表示相關的 php 執行的太慢(php code太複雜?或有bug?)
request method       - the request method (GET, POST, ...);
request URI          - the request URI with the query string;
content length       - the content length of the request (only with POST);
user                 - the user (PHP_AUTH_USER) (or '-' if not set);
script               - the main script called (or '-' if not set);
last request cpu     - the %cpu the last request consumed
                       it's always 0 if the process is not in Idle state
                       because CPU calculation is done when the request
                       processing has terminated;
last request memory  - 處理最後一個 request 後,使用的最大記憶體


改善 php-fpm 記憶體洩漏問題

注意
這方法 並不是真正解決 php-fpm 記憶體洩漏問題
而是讓占用記憶體的 php-fpm 早一點 "自動關閉",釋放出記憶體


修改檔案 /etc/php-fpm/www.conf

pm.max_requests = 130

原解釋:
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.

pm.max_requests 內定是 0
將這變數設一個值
例如:
pm.max_requests = 100
重啟 php-fpm 後,觀察幾天 再來增減數字


如何設定/啟用 PHP FPM status page

有兩個檔案要設定:

1. php-fpm 設定 修改檔案 /etc/php-fpm/www.conf

pm.status_path = /fpm_status

2. apahce httpd 設定

/etc/httpd/httpd.conf
<LocationMatch "/fpm_status123">
    Order Allow,Deny
    Allow from 127.0.0.1 123.xx.xx.xx 輸入允許瀏覽此網頁的IP(自己的IP)
    ProxyPass unix:/var/run/php-fpm/www.sock|fcgi://localhost/fpm_status
</LocationMatch>

# /var/run/php-fpm/www.sock 要跟檔案 /etc/php-fpm/www.conf 中的 listen= 相同
# 例如 listen = /var/run/php-fpm/www.sock

設定完

再重啟 php-fpm、apache httpd 即可

重啟 php-fpm
systemctl reload php-fpm


重啟 apache httpd
apachectl graceful


輸入網址即可看到 php-fpm 狀態
http://SERVER_IP/fpm_status123?full
分類:雲端      54
Tag php , php-fpm ,
留言

留言
top