最後更新: 2019-01-25
介紹
PHP-FPM (FastCGI Process Manager)
https://php-fpm.org/
PHP-FPM 的改進
定制
ability to start workers with different uid/gid/chroot/environment, listening on different ports and using different php.ini
(no more messing around with suphp or suexec - or, indeed, mod_php. )
"slowlog" - logging scripts
not just their names, but their PHP backtraces too,
using ptrace and similar things to read remote process' execute_data) that are executed unusually slow;
目錄
- Apache 2.2 Config
- Apache 2.4 Config
- Install
- Number of socket limit
- php-fpm config
- php getallheaders() function
- ius package
- Check php-fpm Status (By cli - fcgi)
- Enable slowlog
- opcache
Apache 2.2 Config
vhosts.conf
<VirtualHost *:80> Servername example.com DirectoryIndex index.php SuexecUserGroup someuser someuser AddHandler fcgid-script .php FcgidWrapper /var/www/fcgi-bin/someuser/php.fcgi .php <Directory /home/someuser/public_html/> Options +ExecCGI </Directory> </VirtualHost>
mkdir /var/www/fcgi-bin/
mkdir /var/www/fcgi-bin/someuser/
chown -R someuser:someuser /var/www/fcgi-bin/someuser/
chmod a+x /var/www/fcgi-bin/someuser/php.fcgi
File: /var/www/fcgi-bin/someuser/php.fcgi
#!/bin/bash exec /usr/bin/php-cgi
Apache 2.4 Config
用 proxy module 去 connect php-fpm
Centos 7
/etc/httpd/conf.modules.d/00-proxy.conf
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
* mod_proxy_fcgi now supports unix sockets since 2.4.9
Test:
apachectl -M | grep proxy
proxy_module (shared) proxy_fcgi_module (shared)
vhosts.conf
SetHandler
... <Directory /var/www/datahunter.org/web> # Proxy via handler <FilesMatch ".+\.php$"> SetHandler application/x-httpd-php SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch> ... </Directory> ...
OR
ProxyPassMatch
ProxyPassMatch ^/(.*\.php[345]?(/.*)?)$ fcgi://127.0.0.1:9000/var/www/clients/client3/web4/web/$1
Notes:
如無必要, 勿包住它
<IfModule mod_proxy_fcgi.c> ... </IfModule>
當 php-fpm 死了時, Browser 會見到
503 - Service Unavailable
Install php-fpm
# -v Version number
/opt/php70/sbin/php-fpm -v
PHP 7.0.27 (fpm-fcgi) (built: Jan 25 2018 17:29:45) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
# -i PHP information
/opt/php70/sbin/php-fpm -i
phpinfo() PHP Version => 7.0.27 System => Linux vm.laddermission.hk 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 Build Date => Jan 25 2018 17:27:39 Configure Command => './configure' ...
# -m how compiled in modules
[PHP Modules] bcmath bz2 calendar cgi-fcgi Core ...
# Debug
/opt/php70/sbin/php-fpm -t
[26-Jan-2018 10:52:13] NOTICE: configuration file /opt/php70/etc/php-fpm.conf test is successful
-F, --nodaemonize force to stay in foreground
# start it manually with
php-fpm -y /path/to/php-fpm.conf -c /path/to/custom/php.ini
Number of socket limit
php-fpm using too many sockets will cause apache to give a "Cannot assign requested address: error."
This means your operating system is not allowing new sockets to be created.
php-fpm config
/opt/php70/etc/php-fpm.conf
... include=/opt/php70/etc/php-fpm.d/*.conf
# Default Pool File
/opt/php70/etc/php-fpm.d/www.conf
; pool name ('www' here) [www] ; Per pool prefix ; It only applies on the following directives: ; 'access.log' 'slowlog' 'listen' (unixsocket) 'chroot' 'chdir' 'php_values' 'php_admin_values' ; Note: This directive can also be relative to the global prefix. ; $pool Folder 要建立好 prefix = var/run/pools/$pool user = apache group = apache ;listen = 127.0.0.1:9000 ;listen.allowed_clients = 127.0.0.1 listen = $pool listen.owner = apache listen.group = apache listen.mode = 0660 ; static - a fixed number (pm.max_children) of child processes; ; dynamic - pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers pm = dynamic pm.max_requests = 500 ; ulimit -n ; ulimit -u rlimit_files = 1024 rlimit_core = 0 ; Redirect worker stdout and stderr into main error log. ; Note: on highloaded environement, this can cause some delay in the page ; Default Value: no ;catch_workers_output = yes ; Limits the extensions of the main script FPM will allow to parse. ; Default Value: .php security.limit_extensions = .php ; php ini setting php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@mydomain php_flag[display_errors] = off php_admin_value[error_log] = /var/log/fpm-php.www.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 256M php_admin_value[short_open_tag] = on php_admin_value[max_execution_time] = 120 # upload php_admin_value[upload_max_filesize] = 10M php_admin_value[post_max_size] = 20M
# 重啟 php-fpm script
/root/scripts/restart-php-fpm
#!/bin/bash killall php-fpm sleep 3 killall -9 php-fpm /opt/php70/sbin/php-fpm
迷你設定檔 web4.conf
[web4] listen = 127.0.0.1:9013 listen.allowed_clients = 127.0.0.1 user = web4 group = client3 pm = dynamic pm.max_children = 8 pm.start_servers = 2 pm.min_spare_servers = 2 pm.max_spare_servers = 5 pm.max_requests = 0 chdir = /
php getallheaders() function
php-fpm 沒有 getallheaders function, 所以我地要人手加上去
index.php
require_once(__DIR__."/function/function.php");
function/function.php
<? if (!function_exists('getallheaders')) { function getallheaders() { $headers = []; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') { $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; } } return $headers; } } ?>
ius package
yum list | grep php70u-fpm
php70u-fpm.x86_64 7.0.26-1.ius.el7 ius
rpm -ql php-fpm
/etc/php-fpm.conf /etc/php-fpm.d/www.conf
remi Package
/opt/remi/php56/root/etc/php-fpm.d
Check php-fpm Status (By cli - fcgi)
Tools: cgi-fcgi (CLI)
# epel
yum install fcgi
ping/pong
www.conf
# Default 沒有此設定, 所以訪問 /ping 沒有 pong 回應 ping.path = /ping ping.response = pong
Test
port=9000 SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET \ cgi-fcgi -bind -connect 127.0.0.1:$port
Output
Content-type: text/plain;charset=UTF-8 Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-Control: no-cache, no-store, must-revalidate, max-age=0 pong
Short / Full Status
www.conf
; Default Value: not set pm.status_path = /status
Short status
Full status
Exampe
short
SCRIPT_NAME=/status SCRIPT_FILENAME=/status REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000
full
SCRIPT_NAME=/status SCRIPT_FILENAME=/status QUERY_STRING=full REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000
Output
pool: www process manager: dynamic start time: 26/Jan/2018:15:43:14 +0800 start since: 39 accepted conn: 1 listen queue: 0 max listen queue: 0 listen queue len: 128 idle processes: 1 active processes: 1 total processes: 2 max active processes: 1 max children reached: 0 slow requests: 0
說明
listen queue
the number of request in the queue of pending connections (see backlog in listen(2));
max listen queue
the maximum number of requests in the queue of pending connections since FPM has started;
Proxy Timout
Log
[..] [proxy_fcgi:error] [pid 29806] (70007)The timeout specified has expired: [client r.r.r.r:p] AH01075: Error dispatching request to :
Fix
<Proxy "fcgi://127.0.0.1:9000"> ProxySet timeout=180 </Proxy> <FilesMatch ".+\.php$"> SetHandler application/x-httpd-php SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch>
Enable slowlog
www.conf
slowlog = log/$pool.log.slow request_slowlog_timeout = 10
opcache
沒有 opcache 時, php-fpm 會有大量 RAED
Total DISK READ : 10.98 M/s | Total DISK WRITE : 149.32 K/s Actual DISK READ: 10.73 M/s | Actual DISK WRITE: 4.97 M/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 989 be/4 web4 1799.66 K/s 0.00 B/s 0.14 % 80.91 % php-fpm: pool web4 517 be/4 web4 624.77 K/s 0.00 B/s 0.00 % 76.37 % php-fpm: pool web4 1119 be/4 web4 895.90 K/s 0.00 B/s 0.49 % 76.22 % php-fpm: pool web4 526 be/4 web4 919.48 K/s 0.00 B/s 2.63 % 74.94 % php-fpm: pool web4 1134 be/4 web4 1296.70 K/s 0.00 B/s 2.02 % 74.94 % php-fpm: pool web4 1194 be/4 web4 546.19 K/s 0.00 B/s 0.10 % 74.05 % php-fpm: pool web4 475 be/4 web4 1807.52 K/s 0.00 B/s 4.82 % 73.06 % php-fpm: pool web4 1227 be/4 web4 609.06 K/s 0.00 B/s 0.60 % 72.82 % php-fpm: pool web4 464 be/4 web4 1583.55 K/s 0.00 B/s 5.14 % 72.37 % php-fpm: pool web4 1144 be/4 web4 1159.17 K/s 0.00 B/s 4.43 % 70.42 % php-fpm: pool web4
Install
yum install php70-php-opcache
vim /etc/opt/remi/php70/php.d/10-opcache.ini
service php70-php-fpm restart
Doc