PHP - PHP-FPM - 学习/实践

1.应用场景

主要用于弄清楚Nginx+PHP-FPM的运行机制,以及各种配置使用和优化,帮助开发项目。

2.学习/操作

1.文档阅读

Nginx-->进阶-->原理-->Nginx+php+fastcgi的原理与关系 - mangguo - 博客园

PHP - CGI, Fast-FGI, PHP-FPM - 学习/实践_穿素白衫的中少年的博客-CSDN博客

网络协议概论 | Laravel 学院 - CGI、FastCGI 与 PHP-FPM 的前世今生

网络协议概论 | Laravel 学院 - 基于 Nginx + PHP 驱动 Web 应用(上):配置文件与虚拟主机篇

https://blog.csdn.net/william_n/article/details/127394863

https://blog.csdn.net/william_n/article/details/127397801

https://blog.csdn.net/william_n/article/details/127468354

视频教程

cgi、php-cgi 、fastcgi 、php-fpm之间的关系_哔哩哔哩_bilibili

2.整理输出

2.1 介绍

在介绍基于 Nginx + PHP-FPM 实现 PHP Web 项目请求处理及响应发送完整流程之前,有必要先给大家简单科普下 PHP-FPM。

PHP-FPM 的全称是 PHP FastCGI Process Manager,即 PHP FastCGI 进程管理器。

要了解 PHP-FPM ,首先要看看 CGI 与 FastCGI 的关系。

CGI 的英文全名是 Common Gateway Interface,即通用网关接口,是 Web 服务器调用外部程序时所使用的一种服务端应用的规范。

早期的 Web 通信只是按照客户端请求将保存在 Web 服务器硬盘中的数据转发过去而已,这种情况下客户端每次获取的信息也是同样的内容(即静态请求,比如图片、样式文件、HTML文档),而随着 Web 的发展,Web 所能呈现的内容更加丰富,与用户的交互日益频繁,比如博客、论坛、电商网站、社交网络等,这个时候仅仅通过静态资源已经无法满足 Web 通信的需求,所以引入 CGI 以便客户端请求能够触发 Web 服务器运行另一个外部程序,客户端所输入的数据也会传给这个外部程序,该程序运行结束后会将生成的 HTML 和其他数据通过 Web 服务器再返回给客户端(即动态请求,比如基于 PHP、Python、Java 实现的应用)。

利用 CGI 可以针对用户请求动态返回给客户端各种各样动态变化的信息。

FastCGI 顾名思义,是 CGI 的升级版本,为了提升 CGI 的性能而生,CGI 针对每个 HTTP 请求都会 fork 一个新进程来进行处理(解析配置文件、初始化执行环境、处理请求),然后把这个进程处理完的结果通过 Web 服务器转发给用户,刚刚 fork 的新进程也随之退出,如果下次用户再请求动态资源,那么 Web 服务器又再次 fork 一个新进程,如此周而复始循环往复。

而 FastCGI 则会先 fork 一个 master 进程,解析配置文件,初始化执行环境,然后再 fork 多个 worker 进程(与 Nginx 有点像),当 HTTP 请求过来时,master 进程将其会传递给一个 worker 进程,然后立即可以接受下一个请求,这样就避免了重复的初始化操作,效率自然也就提高了。而且当 worker 进程不够用时,master 进程还可以根据配置预先启动几个 worker 进程等着;当空闲 worker 进程太多时,也会关掉一些,这样不仅提高了性能,还节约了系统资源。

这样一来,PHP-FPM 就好理解了,FastCGI 只是一个协议规范,需要每个语言具体去实现,PHP-FPM 就是 PHP 版本的 FastCGI 协议实现,有了它,就是实现 PHP 脚本与 Web 服务器(通常是 Nginx)之间的通信,同时它也是一个 PHP SAPI,从而构建起 PHP 解释器与 Web 服务器之间的桥梁。

PHP-FPM 负责管理一个进程池来处理来自 Web 服务器的 HTTP 动态请求,在 PHP-FPM 中,master 进程负责与 Web 服务器进行通信,接收 HTTP 请求,再将请求转发给 worker 进程进行处理,worker 进程主要负责动态执行 PHP 代码,处理完成后,将处理结果返回给 Web 服务器,再由 Web 服务器将结果发送给客户端。

这就是 PHP-FPM 的基本工作原理,

PHP-FPM 有自己独立的配置文件 php-fpm.conf 用于对 PHP-FPM 进行配置,见下面。

2.2  php-fpm配置文件

环境

Mac 

Docker + LNMP

Check版本

➜  ~ php-fpm -v

PHP 8.1.9 (fpm-fcgi) (built: Aug  4 2022 14:00:22)

Copyright (c) The PHP Group

Zend Engine v4.1.9, Copyright (c) Zend Technologies

    with Zend OPcache v8.1.9, Copyright (c), by Zend Technologies

➜  ~ php -v    

PHP 8.1.9 (cli) (built: Aug  4 2022 14:00:20) (NTS)

Copyright (c) The PHP Group

Zend Engine v4.1.9, Copyright (c) Zend Technologies

    with Zend OPcache v8.1.9, Copyright (c), by Zend Technologies

➜  ~

PHP-FPM已经集成在PHP中,也就是和PHP版本保持一致

php和phpfpm的区别:

1、php是在服务器端执行的脚本语言,而phpfpm是一个PHPFastCGI管理器;

2、对于PHP5.3.3之前的php来说,phpfpm是一个补丁包;

3、PHP5.3.3已经集成php-fpm。

这里是使用mac homebrew进行安装的

➜  sbin git:(stable) ls

php-fpm

➜  sbin git:(stable) pwd

/opt/homebrew/opt/php@7.2/sbin

➜  sbin git:(stable) ./php-fpm -v

dyld[73377]: Library not loaded: '/opt/homebrew/opt/icu4c/lib/libicui18n.71.dylib'

  Referenced from: '/opt/homebrew/Cellar/php@7.2/7.2.34_5/sbin/php-fpm'

  Reason: tried: '/opt/homebrew/opt/icu4c/lib/libicui18n.71.dylib' (no such file), '/usr/local/lib/libicui18n.71.dylib' (no such file), '/usr/lib/libicui18n.71.dylib' (no such file), '/opt/homebrew/Cellar/icu4c/70.1/lib/libicui18n.71.dylib' (no such file), '/usr/local/lib/libicui18n.71.dylib' (no such file), '/usr/lib/libicui18n.71.dylib' (no such file)

[1]    73377 abort      ./php-fpm -v

➜  sbin git:(stable) php-fpm -v

PHP 8.1.9 (fpm-fcgi) (built: Aug  4 2022 14:00:22)

Copyright (c) The PHP Group

Zend Engine v4.1.9, Copyright (c) Zend Technologies

    with Zend OPcache v8.1.9, Copyright (c), by Zend Technologies

➜  sbin git:(stable) which php-fpm

/opt/homebrew/sbin/php-fpm

➜  sbin git:(stable)

这里出现报错:

➜  ~ php72 -v

dyld[74083]: Library not loaded: '/opt/homebrew/opt/icu4c/lib/libicui18n.71.dylib'

  Referenced from: '/opt/homebrew/Cellar/php@7.2/7.2.34_5/bin/php'

  Reason: tried: '/opt/homebrew/opt/icu4c/lib/libicui18n.71.dylib' (no such file), '/usr/local/lib/libicui18n.71.dylib' (no such file), '/usr/lib/libicui18n.71.dylib' (no such file), '/opt/homebrew/Cellar/icu4c/70.1/lib/libicui18n.71.dylib' (no such file), '/usr/local/lib/libicui18n.71.dylib' (no such file), '/usr/lib/libicui18n.71.dylib' (no such file)

[1]    74083 abort      /opt/homebrew/opt/php@7.2/bin/php -v

➜  ~

原因和解决办法,参见

问题/补充 -- 

配置别名

1). 配置文件 -- docker中php-fpm容器

建议参见:

https://gitee.com/william_ning/conf-files

https://github.com/ningxiaofa/conf-files/tree/main/php-fpm/docker/7.2

网络协议概论 | Laravel 学院

强烈建议,应该将配置文件的内容看几遍,最好是很熟悉。

这也是学习一种工具/服务/软件 最好的方式「学习一门工具最好的方式,就多使用,而且达到非常熟悉

目录结构

php-fpm.conf

;;;;;;;;;;;;;;;;;;;;;

; FPM Configuration ;

;;;;;;;;;;;;;;;;;;;;;

; All relative paths in this configuration file are relative to PHP's install

; prefix (/usr/local). This prefix can be dynamically changed by using the

; '-p' argument from the command line.

;;;;;;;;;;;;;;;;;;

; Global Options ;

;;;;;;;;;;;;;;;;;;

[global]

; Pid file

; Note: the default prefix is /usr/local/var

; Default Value: none

;pid = run/php-fpm.pid

; Error log file

; If it's set to "syslog", log is sent to syslogd instead of being written

; into a local file.

; Note: the default prefix is /usr/local/var

; Default Value: log/php-fpm.log

;error_log = log/php-fpm.log

; syslog_facility is used to specify what type of program is logging the

; message. This lets syslogd specify that messages from different facilities

; will be handled differently.

; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)

; Default Value: daemon

;syslog.facility = daemon

; syslog_ident is prepended to every message. If you have multiple FPM

; instances running on the same server, you can change the default value

; which must suit common needs.

; Default Value: php-fpm

;syslog.ident = php-fpm

; Log level

; Possible Values: alert, error, warning, notice, debug

; Default Value: notice

;log_level = notice

; Log limit on number of characters in the single line (log entry). If the

; line is over the limit, it is wrapped on multiple lines. The limit is for

; all logged characters including message prefix and suffix if present. However

; the new line character does not count into it as it is present only when

; logging to a file descriptor. It means the new line character is not present

; when logging to syslog.

; Default Value: 1024

;log_limit = 4096

; Log buffering specifies if the log line is buffered which means that the

; line is written in a single write operation. If the value is false, then the

; data is written directly into the file descriptor. It is an experimental

; option that can potentionaly improve logging performance and memory usage

; for some heavy logging scenarios. This option is ignored if logging to syslog

; as it has to be always buffered.

; Default value: yes

;log_buffering = no

; If this number of child processes exit with SIGSEGV or SIGBUS within the time

; interval set by emergency_restart_interval then FPM will restart. A value

; of '0' means 'Off'.

; Default Value: 0

;emergency_restart_threshold = 0

; Interval of time used by emergency_restart_interval to determine when

; a graceful restart will be initiated. This can be useful to work around

; accidental corruptions in an accelerator's shared memory.

; Available Units: s(econds), m(inutes), h(ours), or d(ays)

; Default Unit: seconds

; Default Value: 0

;emergency_restart_interval = 0

; Time limit for child processes to wait for a reaction on signals from master.

; Available units: s(econds), m(inutes), h(ours), or d(ays)

; Default Unit: seconds

; Default Value: 0

;process_control_timeout = 0

; The maximum number of processes FPM will fork. This has been designed to control

; the global number of processes when using dynamic PM within a lot of pools.

; Use it with caution.

; Note: A value of 0 indicates no limit

; Default Value: 0

; process.max = 128

; Specify the nice(2) priority to apply to the master process (only if set)

; The value can vary from -19 (highest priority) to 20 (lowest priority)

; Note: - It will only work if the FPM master process is launched as root

; - The pool process will inherit the master process priority

; unless specified otherwise

; Default Value: no set

; process.priority = -19

; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.

; Default Value: yes

;daemonize = yes

; Set open file descriptor rlimit for the master process.

; Default Value: system defined value

;rlimit_files = 1024

; Set max core size rlimit for the master process.

; Possible Values: 'unlimited' or an integer greater or equal to 0

; Default Value: system defined value

;rlimit_core = 0

; Specify the event mechanism FPM will use. The following is available:

; - select (any POSIX os)

; - poll (any POSIX os)

; - epoll (linux >= 2.5.44)

; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)

; - /dev/poll (Solaris >= 7)

; - port (Solaris >= 10)

; Default Value: not set (auto detection)

;events.mechanism = epoll

; When FPM is built with systemd integration, specify the interval,

; in seconds, between health report notification to systemd.

; Set to 0 to disable.

; Available Units: s(econds), m(inutes), h(ours)

; Default Unit: seconds

; Default value: 10

;systemd_interval = 10

;;;;;;;;;;;;;;;;;;;;

; Pool Definitions ;

;;;;;;;;;;;;;;;;;;;;

; Multiple pools of child processes may be started with different listening

; ports and different management options. The name of the pool will be

; used in logs and stats. There is no limitation on the number of pools which

; FPM can handle. Your system will tell you anyway :)

; Include one or more files. If glob(3) exists, it is used to include a bunch of

; files from a glob(3) pattern. This directive can be used everywhere in the

; file.

; Relative path can also be used. They will be prefixed by:

; - the global prefix if it's been set (-p argument)

; - /usr/local otherwise

include=etc/php-fpm.d/*.conf

项目配置

[root@ip-172-31-5-63 ~]# cd /etc

[root@ip-172-31-5-63 etc]# ls -1

adjtime

aliases

aliases.db

alternatives

anacrontab

audisp

audit

bash_completion.d

bashrc

binfmt.d

centos-release

centos-release-upstream

chkconfig.d

chrony.conf

chrony.keys

cloud

cron.d

cron.daily

cron.deny

cron.hourly

cron.monthly

crontab

cron.weekly

crypttab

csh.cshrc

csh.login

dbus-1

default

depmod.d

dhcp

DIR_COLORS

DIR_COLORS.256color

DIR_COLORS.lightbgcolor

dracut.conf

dracut.conf.d

e2fsck.conf

environment

exports

exports.d

filesystems

firewalld

fstab

gcrypt

GeoIP.conf

GeoIP.conf.default

gnupg

GREP_COLORS

groff

group

group-

grub2.cfg

grub.conf

grub.d

gshadow

gshadow-

gss

gssproxy

host.conf

hostname

hosts

hosts.allow

hosts.deny

idmapd.conf

init.d

inittab

inputrc

iproute2

issue

issue.net

kdump.conf

kernel

krb5.conf

krb5.conf.d

ld.so.cache

ld.so.conf

ld.so.conf.d

libaudit.conf

libnl

libuser.conf

locale.conf

localtime

login.defs

logrotate.conf

logrotate.d

machine-id

magic

makedumpfile.conf.sample

man_db.conf

mke2fs.conf

modprobe.d

modules-load.d

motd

mtab

my.cnf

my.cnf.d

netconfig

NetworkManager

networks

newrelic-infra

nfs.conf

nfsmount.conf

nginx

nsswitch.conf

nsswitch.conf.bak

nsswitch.conf.rpmnew

openldap

opt

os-release

pam.d

passwd

passwd-

php.d

php-fpm.conf

php-fpm.d

php.ini

php-zts.d

pkcs11

pki

pm

polkit-1

popt.d

postfix

ppp

prelink.conf.d

printcap

profile

profile.d

protocols

python

qemu-ga

rc0.d

rc1.d

rc2.d

rc3.d

rc4.d

rc5.d

rc6.d

rc.d

rc.local

redhat-release

redis.conf

redis-sentinel.conf

request-key.conf

request-key.d

resolv.conf

rpc

rpm

rsyncd.conf

rsyslog.conf

rsyslog.d

rwtab

rwtab.d

sasl2

securetty

security

selinux

services

sestatus.conf

shadow

shadow-

shells

skel

ssh

ssl

statetab

statetab.d

subgid

subuid

sudo.conf

sudoers

sudoers.d

sudo-ldap.conf

sysconfig

sysctl.conf

sysctl.d

systemd

system-release

system-release-cpe

td-agent-bit

terminfo

tmpfiles.d

trusted-key.key

tuned

udev

vconsole.conf

vimrc

virc

wgetrc

wpa_supplicant

X11

xdg

xinetd.d

yum

yum.conf

yum.repos.d

[root@ip-172-31-5-63 etc]# cat php-fpm.conf

;;;;;;;;;;;;;;;;;;;;;

; FPM Configuration ;

;;;;;;;;;;;;;;;;;;;;;

; All relative paths in this configuration file are relative to PHP's install

; prefix. This prefix can be dynamically changed by using the

; '-p' argument from the command line.

;;;;;;;;;;;;;;;;;;

; Global Options ;

;;;;;;;;;;;;;;;;;;

[global]

; Pid file

; Default Value: none

pid = /var/run/php-fpm/php-fpm.pid

; Error log file

; If it's set to "syslog", log is sent to syslogd instead of being written

; in a local file.

; Default Value: log/php-fpm.log

error_log = /var/log/php-fpm/error.log

; syslog_facility is used to specify what type of program is logging the

; message. This lets syslogd specify that messages from different facilities

; will be handled differently.

; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)

; Default Value: daemon

;syslog.facility = daemon

; syslog_ident is prepended to every message. If you have multiple FPM

; instances running on the same server, you can change the default value

; which must suit common needs.

; Default Value: php-fpm

;syslog.ident = php-fpm

; Log level

; Possible Values: alert, error, warning, notice, debug

; Default Value: notice

;log_level = notice

; If this number of child processes exit with SIGSEGV or SIGBUS within the time

; interval set by emergency_restart_interval then FPM will restart. A value

; of '0' means 'Off'.

; Default Value: 0

;emergency_restart_threshold = 0

; Interval of time used by emergency_restart_interval to determine when

; a graceful restart will be initiated.  This can be useful to work around

; accidental corruptions in an accelerator's shared memory.

; Available Units: s(econds), m(inutes), h(ours), or d(ays)

; Default Unit: seconds

; Default Value: 0

;emergency_restart_interval = 0

; Time limit for child processes to wait for a reaction on signals from master.

; Available units: s(econds), m(inutes), h(ours), or d(ays)

; Default Unit: seconds

; Default Value: 0

;process_control_timeout = 0

; The maximum number of processes FPM will fork. This has been design to control

; the global number of processes when using dynamic PM within a lot of pools.

; Use it with caution.

; Note: A value of 0 indicates no limit

; Default Value: 0

; process.max = 128

; Specify the nice(2) priority to apply to the master process (only if set)

; The value can vary from -19 (highest priority) to 20 (lower priority)

; Note: - It will only work if the FPM master process is launched as root

;       - The pool process will inherit the master process priority

;         unless it specified otherwise

; Default Value: no set

; process.priority = -19

; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.

; Default Value: yes

daemonize = yes

; Set open file descriptor rlimit for the master process.

; Default Value: system defined value

;rlimit_files = 1024

; Set max core size rlimit for the master process.

; Possible Values: 'unlimited' or an integer greater or equal to 0

; Default Value: system defined value

;rlimit_core = 0

; Specify the event mechanism FPM will use. The following is available:

; - select     (any POSIX os)

; - poll       (any POSIX os)

; - epoll      (linux >= 2.5.44)

; - kqueue     (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)

; - /dev/poll  (Solaris >= 7)

; - port       (Solaris >= 10)

; Default Value: not set (auto detection)

;events.mechanism = epoll

; When FPM is build with systemd integration, specify the interval,

; in second, between health report notification to systemd.

; Set to 0 to disable.

; Available Units: s(econds), m(inutes), h(ours)

; Default Unit: seconds

; Default value: 10

;systemd_interval = 10

;;;;;;;;;;;;;;;;;;;;

; Pool Definitions ;

;;;;;;;;;;;;;;;;;;;;

; Multiple pools of child processes may be started with different listening

; ports and different management options.  The name of the pool will be

; used in logs and stats. There is no limitation on the number of pools which

; FPM can handle. Your system will tell you anyway :)

; Include one or more files. If glob(3) exists, it is used to include a bunch of

; files from a glob(3) pattern. This directive can be used everywhere in the

; file.

include=/etc/php-fpm.d/*.conf[root@ip-172-31-5-63 etc]# pwd

/etc

[root@ip-172-31-5-63 etc]# 

php-fpm.d目录下

www.conf 「当然可以有多个pool,也就是conf文件,而且,文件名和pool名保持一致

; Start a new pool named 'www'.

; the variable $pool can be used in any directive and will be replaced by the

; 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'

; When not set, the global prefix (or NONE) applies instead.

; Note: This directive can also be relative to the global prefix.

; Default Value: none

;prefix = /path/to/pools/$pool

; Unix user/group of processes

; Note: The user is mandatory. If the group is not set, the default user's group

; will be used.

user = www-data

group = www-data

; The address on which to accept FastCGI requests.

; Valid syntaxes are:

; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on

; a specific port;

; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on

; a specific port;

; 'port' - to listen on a TCP socket to all addresses

; (IPv6 and IPv4-mapped) on a specific port;

; '/path/to/unix/socket' - to listen on a unix socket.

; Note: This value is mandatory.

listen = 127.0.0.1:9000

; Set listen(2) backlog.

; Default Value: 511 (-1 on FreeBSD and OpenBSD)

;listen.backlog = 511

; Set permissions for unix socket, if one is used. In Linux, read/write

; permissions must be set in order to allow connections from a web server. Many

; BSD-derived systems allow connections regardless of permissions. The owner

; and group can be specified either by name or by their numeric IDs.

; Default Values: user and group are set as the running user

; mode is set to 0660

;listen.owner = www-data

;listen.group = www-data

;listen.mode = 0660

; When POSIX Access Control Lists are supported you can set them using

; these options, value is a comma separated list of user/group names.

; When set, listen.owner and listen.group are ignored

;listen.acl_users =

;listen.acl_groups =

; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect.

; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original

; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address

; must be separated by a comma. If this value is left blank, connections will be

; accepted from any ip address.

; Default Value: any

;listen.allowed_clients = 127.0.0.1

; Specify the nice(2) priority to apply to the pool processes (only if set)

; The value can vary from -19 (highest priority) to 20 (lower priority)

; Note: - It will only work if the FPM master process is launched as root

; - The pool processes will inherit the master process priority

; unless it specified otherwise

; Default Value: no set

; process.priority = -19

; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user

; or group is differrent than the master process user. It allows to create process

; core dump and ptrace the process for the pool user.

; Default Value: no

; process.dumpable = yes

; Choose how the process manager will control the number of child processes.

; Possible Values:

; static - a fixed number (pm.max_children) of child processes;

; dynamic - the number of child processes are set dynamically based on the

; following directives. With this process management, there will be

; always at least 1 children.

; pm.max_children - the maximum number of children that can

; be alive at the same time.

; pm.start_servers - the number of children created on startup.

; pm.min_spare_servers - the minimum number of children in 'idle'

; state (waiting to process). If the number

; of 'idle' processes is less than this

; number then some children will be created.

; pm.max_spare_servers - the maximum number of children in 'idle'

; state (waiting to process). If the number

; of 'idle' processes is greater than this

; number then some children will be killed.

; ondemand - no children are created at startup. Children will be forked when

; new requests will connect. The following parameter are used:

; pm.max_children - the maximum number of children that

; can be alive at the same time.

; pm.process_idle_timeout - The number of seconds after which

; an idle process will be killed.

; Note: This value is mandatory.

pm = dynamic

; The number of child processes to be created when pm is set to 'static' and the

; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.

; This value sets the limit on the number of simultaneous requests that will be

; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.

; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP

; CGI. The below defaults are based on a server without much resources. Don't

; forget to tweak pm.* to fit your needs.

; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'

; Note: This value is mandatory.

pm.max_children = 5

; The number of child processes created on startup.

; Note: Used only when pm is set to 'dynamic'

; Default Value: (min_spare_servers + max_spare_servers) / 2

pm.start_servers = 2

; 所需的最小空闲服务器进程数。

; The desired minimum number of idle server processes.

; Note: Used only when pm is set to 'dynamic'

; Note: Mandatory when pm is set to 'dynamic'

pm.min_spare_servers = 1

; 所需的最大空闲服务器进程数。

; The desired maximum number of idle server processes.

; Note: Used only when pm is set to 'dynamic'

; Note: Mandatory when pm is set to 'dynamic'

pm.max_spare_servers = 3

; 空闲进程将被终止的秒数。

; The number of seconds after which an idle process will be killed.

; Note: Used only when pm is set to 'ondemand'

; Default Value: 10s

;pm.process_idle_timeout = 10s;

; 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.

; Default Value: 0

;pm.max_requests = 500

; The URI to view the FPM status page. If this value is not set, no URI will be

; recognized as a status page. It shows the following informations:

; pool - the name of the pool;

; process manager - static, dynamic or ondemand;

; start time - the date and time FPM has started;

; start since - number of seconds since FPM has started;

; accepted conn - the number of request accepted by the pool;

; 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;

; listen queue len - the size of the socket queue of pending connections;

; idle processes - the number of idle processes;

; active processes - the number of active processes;

; total processes - the number of idle + active processes;

; max active processes - the maximum number of active processes since FPM

; has started;

; max children reached - number of times, the process limit has been reached,

; when pm tries to start more children (works only for

; pm 'dynamic' and 'ondemand');

; Value are updated in real time.

; Example output:

; pool: www

; process manager: static

; start time: 01/Jul/2011:17:53:49 +0200

; start since: 62636

; accepted conn: 190460

; listen queue: 0

; max listen queue: 1

; listen queue len: 42

; idle processes: 4

; active processes: 11

; total processes: 15

; max active processes: 12

; max children reached: 0

;

; By default the status page output is formatted as text/plain. Passing either

; 'html', 'xml' or 'json' in the query string will return the corresponding

; output syntax. Example:

; http://www.foo.bar/status

; http://www.foo.bar/status?json

; http://www.foo.bar/status?html

; http://www.foo.bar/status?xml

;

; By default the status page only outputs short status. Passing 'full' in the

; query string will also return status for each pool process.

; Example:

; http://www.foo.bar/status?full

; http://www.foo.bar/status?json&full

; http://www.foo.bar/status?html&full

; http://www.foo.bar/status?xml&full

; The Full status returns for each process:

; 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 - the number of seconds since the process has started;

; requests - the number of requests the process has served;

; request duration - the duration in µs of the requests;

; 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 - the max amount of memory the last request consumed

; it's always 0 if the process is not in Idle state

; because memory calculation is done when the request

; processing has terminated;

; If the process is in Idle state, then informations are related to the

; last request the process has served. Otherwise informations are related to

; the current request being served.

; Example output:

; ************************

; pid: 31330

; state: Running

; start time: 01/Jul/2011:17:53:49 +0200

; start since: 63087

; requests: 12808

; request duration: 1250261

; request method: GET

; request URI: /test_mem.php?N=10000

; content length: 0

; user: -

; script: /home/fat/web/docs/php/test_mem.php

; last request cpu: 0.00

; last request memory: 0

;

; Note: There is a real-time FPM status monitoring sample web page available

; It's available in: /usr/local/share/php/fpm/status.html

;

; Note: The value must start with a leading slash (/). The value can be

; anything, but it may not be a good idea to use the .php extension or it

; may conflict with a real PHP file.

; Default Value: not set

;pm.status_path = /status

; The ping URI to call the monitoring page of FPM. If this value is not set, no

; URI will be recognized as a ping page. This could be used to test from outside

; that FPM is alive and responding, or to

; - create a graph of FPM availability (rrd or such);

; - remove a server from a group if it is not responding (load balancing);

; - trigger alerts for the operating team (24/7).

; Note: The value must start with a leading slash (/). The value can be

; anything, but it may not be a good idea to use the .php extension or it

; may conflict with a real PHP file.

; Default Value: not set

;ping.path = /ping

; This directive may be used to customize the response of a ping request. The

; response is formatted as text/plain with a 200 response code.

; Default Value: pong

;ping.response = pong

; The access log file

; Default: not set

;access.log = log/$pool.access.log

; The access log format.

; The following syntax is allowed

; %%: the '%' character

; %C: %CPU used by the request

; it can accept the following format:

; - %{user}C for user CPU only

; - %{system}C for system CPU only

; - %{total}C for user + system CPU (default)

; %d: time taken to serve the request

; it can accept the following format:

; - %{seconds}d (default)

; - %{miliseconds}d

; - %{mili}d

; - %{microseconds}d

; - %{micro}d

; %e: an environment variable (same as $_ENV or $_SERVER)

; it must be associated with embraces to specify the name of the env

; variable. Some exemples:

; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e

; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e

; %f: script filename

; %l: content-length of the request (for POST request only)

; %m: request method

; %M: peak of memory allocated by PHP

; it can accept the following format:

; - %{bytes}M (default)

; - %{kilobytes}M

; - %{kilo}M

; - %{megabytes}M

; - %{mega}M

; %n: pool name

; %o: output header

; it must be associated with embraces to specify the name of the header:

; - %{Content-Type}o

; - %{X-Powered-By}o

; - %{Transfert-Encoding}o

; - ....

; %p: PID of the child that serviced the request

; %P: PID of the parent of the child that serviced the request

; %q: the query string

; %Q: the '?' character if query string exists

; %r: the request URI (without the query string, see %q and %Q)

; %R: remote IP address

; %s: status (response code)

; %t: server time the request was received

; it can accept a strftime(3) format:

; %d/%b/%Y:%H:%M:%S %z (default)

; The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag

; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t

; %T: time the log has been written (the request has finished)

; it can accept a strftime(3) format:

; %d/%b/%Y:%H:%M:%S %z (default)

; The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag

; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t

; %u: remote user

;

; Default: "%R - %u %t \"%m %r\" %s"

;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"

; The log file for slow requests

; Default Value: not set

; Note: slowlog is mandatory if request_slowlog_timeout is set

;slowlog = log/$pool.log.slow

; The timeout for serving a single request after which a PHP backtrace will be

; dumped to the 'slowlog' file. A value of '0s' means 'off'.

; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)

; Default Value: 0

;request_slowlog_timeout = 0

; Depth of slow log stack trace.

; Default Value: 20

;request_slowlog_trace_depth = 20

; The timeout for serving a single request after which the worker process will

; be killed. This option should be used when the 'max_execution_time' ini option

; does not stop script execution for some reason. A value of '0' means 'off'.

; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)

; Default Value: 0

;request_terminate_timeout = 0

; The timeout set by 'request_terminate_timeout' ini option is not engaged after

; application calls 'fastcgi_finish_request' or when application has finished and

; shutdown functions are being called (registered via register_shutdown_function).

; This option will enable timeout limit to be applied unconditionally

; even in such cases.

; Default Value: no

;request_terminate_timeout_track_finished = no

; Set open file descriptor rlimit.

; Default Value: system defined value

;rlimit_files = 1024

; Set max core size rlimit.

; Possible Values: 'unlimited' or an integer greater or equal to 0

; Default Value: system defined value

;rlimit_core = 0

; Chroot to this directory at the start. This value must be defined as an

; absolute path. When this value is not set, chroot is not used.

; Note: you can prefix with '$prefix' to chroot to the pool prefix or one

; of its subdirectories. If the pool prefix is not set, the global prefix

; will be used instead.

; Note: chrooting is a great security feature and should be used whenever

; possible. However, all PHP paths will be relative to the chroot

; (error_log, sessions.save_path, ...).

; Default Value: not set

;chroot =

; Chdir to this directory at the start.

; Note: relative path can be used.

; Default Value: current directory or / when chroot

;chdir = /var/www

; Redirect worker stdout and stderr into main error log. If not set, stdout and

; stderr will be redirected to /dev/null according to FastCGI specs.

; Note: on highloaded environement, this can cause some delay in the page

; process time (several ms).

; Default Value: no

;catch_workers_output = yes

; Decorate worker output with prefix and suffix containing information about

; the child that writes to the log and if stdout or stderr is used as well as

; log level and time. This options is used only if catch_workers_output is yes.

; Settings to "no" will output data as written to the stdout or stderr.

; Default value: yes

;decorate_workers_output = no

; Clear environment in FPM workers

; Prevents arbitrary environment variables from reaching FPM worker processes

; by clearing the environment in workers before env vars specified in this

; pool configuration are added.

; Setting to "no" will make all environment variables available to PHP code

; via getenv(), $_ENV and $_SERVER.

; Default Value: yes

;clear_env = no

; Limits the extensions of the main script FPM will allow to parse. This can

; prevent configuration mistakes on the web server side. You should only limit

; FPM to .php extensions to prevent malicious users to use other extensions to

; execute php code.

; Note: set an empty value to allow all extensions.

; Default Value: .php

;security.limit_extensions = .php .php3 .php4 .php5 .php7

; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from

; the current environment.

; Default Value: clean env

;env[HOSTNAME] = $HOSTNAME

;env[PATH] = /usr/local/bin:/usr/bin:/bin

;env[TMP] = /tmp

;env[TMPDIR] = /tmp

;env[TEMP] = /tmp

; Additional php.ini defines, specific to this pool of workers. These settings

; overwrite the values previously defined in the php.ini. The directives are the

; same as the PHP SAPI:

; php_value/php_flag - you can set classic ini defines which can

; be overwritten from PHP call 'ini_set'.

; php_admin_value/php_admin_flag - these directives won't be overwritten by

; PHP call 'ini_set'

; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.

; Defining 'extension' will load the corresponding shared extension from

; extension_dir. Defining 'disable_functions' or 'disable_classes' will not

; overwrite previously defined php.ini values, but will append the new value

; instead.

; Note: path INI options can be relative and will be expanded with the prefix

; (pool, global or /usr/local)

; Default Value: nothing is defined by default except the values in php.ini and

; specified at startup with the -d argument

;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com

;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] = 32M

Linux 「某云服务商ECS  配置」

nginx 配置

[root@MrNing nginx]# pwd

/home/williamning/docker-lnmp/etc/nginx

[root@MrNing nginx]# ls

conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params

[root@MrNing nginx]# cat nginx.conf

user  nginx;

worker_processes  auto;

error_log  /var/log/nginx/error.log notice;

pid        /var/run/nginx.pid;

events {

    worker_connections  1024;

}

http {

    include       /etc/nginx/mime.types;

    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

}

[root@MrNing nginx]#

default.conf

[root@MrNing nginx]# cd conf.d/
[root@MrNing conf.d]# pwd
/home/williamning/docker-lnmp/etc/nginx/conf.d
[root@MrNing conf.d]# ls
default.conf
[root@MrNing conf.d]# cat default.conf 
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}


    location ~ \.php$ {
        fastcgi_pass   run-php-74-fpm:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html$fastcgi_script_name;
        fastcgi_param  SCRIPT_NAME      $fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

[root@MrNing conf.d]# 

上面的内容涉及到虚拟主机配置

配置多站点「虚拟主机,并不是只能在本地开发环境才可以创建

但是记住,这里的域名必须是真实有效的域名,而且要备案。

是时候解决自己域名的问题了

[root@MrNing conf.d]# vim default.conf

[root@MrNing conf.d]# cp default.conf app.test.conf

[root@MrNing conf.d]# ls

app.test.conf  default.conf

[root@MrNing conf.d]# vim app.test.conf

[root@MrNing conf.d]# ls

app.test.conf  default.conf

[root@MrNing conf.d]#

2.3 PHP-FPM的进程模型

1). Nginx & PHP-FPM 进程状态

可以看到,都是 一个master进程 + 多个worker进程

均是有配置文件控制其行为。

可以看到:

Nginx和PHP-FPM是相同的进程模型:

一个master进程+多个worker进程

而且都是进程池方式「」

突然的问题:

1. PHP-FPM到底是不是常驻内存「Long-Live」的?

刚开始想通过如下的方式去验证:
通过一个请求,将一个变量处理,然后通过另外一个请求去查看该变量是否发生变化

然后在看了swoole对thinkphp框架做的处理之后,判断是不可行。「而且根据我们的开发经验也知道,不存在这种情况,即便存在这种情况,也要避免

因为即便是常驻内存,也就是在创建worker进程时,加载一次文件,之后进程保持「也就是常驻内存」

之后的请求都不会再加载文件,也会将上一次请求的内容清理干净/还原「主要是超全局变量」然后一边解释编译一边执行「即便在创建进程时,已经加载了PHP文件/框架文件, 但是因为是一边解释一边执行,顺序执行还是不会存在问题,因为根本的区别在于请求的数据的变化,其他的数据变化都是由此而来」,依然不会存在问题。

插入 #20231206 

常驻内存: -------- 此刻的理解

应是指php进程常驻, 但并不意味着php框架(如laravel)是常驻内存的, 保持在php进程中的.

php-fpm则是php worker进程常驻, 但是php脚本的生命周期也是同http请求的生命周期相同, 也就是

在nginx+php-fpm的模式下, 每次http请求, 虽然php worker进程不用创建, php扩展, php.ini不用每次都重载, 但是laravel框架每次都要重新加载一遍, 就要重新解释编译.

swoole则是将后面的laravel框架加载(PHP脚本解释编译)都做了优化, 只要第一次加载编译即可, 后面的请求可以直接执行编译解释后php脚本(字节码 opcode), 速度会相对更快.

来自网友的评论以及个人想法补充:

cgi、php-cgi 、fastcgi 、php-fpm之间的关系_哔哩哔哩_bilibili


PHP 处理动态请求,就两种方式:「不是单指PHP的运行方式,而是处理网络动态请求,而且是目前通常这两种」
1、Swoole HttpServer 基于Cli 
2、Nginx+PHP-FPM 普遍方式 (ThinkPHP Laravel)
均常驻内存,但脚本生命周期完全不同。「TBD,待分析

Fpm 通讯两种方式「php-fpm与nginx的通讯」:

tcp socket:目的是FPM部署到不同服务器上「单独部署,脱离Nginx

unix socket:只能单机通讯,减少网络协议解析开销,传输性能更高但有限制。

如果是Swoole HttpServer,应不存在通讯,因为就是swoole一个人全做了,或者说也是uinx socket ,底层TBD

参见个人文档:「PHP运行方式和模式」

https://blog.csdn.net/william_n/article/details/127468354

解答:

根据文档阅读和思考得出的结论是:

PHP-FPM是长驻内存中。

但是还是要考虑一个问题:

为什么都是常驻内存的方式,PHP-FPM与Swoole的性能差距有些大呢?

参见:

https://blog.csdn.net/william_n/article/details/127482429

2.4 PHP-FPM优化策略和手段

暂时参见:

PHP - CGI, Fast-FGI, PHP-FPM - 学习/实践_穿素白衫的中少年的博客-CSDN博客

后续补充

...

3.问题/补充

1. php-fpm.conf配置文件中的注释

Correct之前之后

可以看到可以使用中文注释。

同时应该保证与已有的注释风格保持一致即可「这个原则适用于所有技术的编码

2. 关于PHP-FP平滑重启

php-fpm进程关闭与重启脚本详解一聚教程网

平滑重启不代表修改了配置文件,不需要执行重启命令「当然,可以通过程序来做,比如检测文件变化,从而执行平滑重启命令」。

所以,在开发/生产环境中,在修改了配置文件后,依然需要手动重启PHP-FPM服务「不需要重启Nginx服务,因为是两个独立的服务

PHP-FPM是一个PHP FastCGI管理器,是只用于PHP的。   

PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。

现在我们可以在最新的PHP 5.3.2的源码树里下载得到直接整合了PHP-FPM的分支,据说下个版本会融合进PHP的主分支去。相对Spawn-FCGI,PHP-FPM在CPU和内存方面的控制都更胜一筹,而且前者很容易崩溃,必须用crontab进行监控,而PHP-FPM则没有这种烦恼。

  

PHP5.3.3已经集成php-fpm了,不再是第三方的包了。

PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以被PHP官方收录了。

在./configure的时候带 –enable-fpm参数即可开启PHP-FPM。   

使用PHP-FPM来控制PHP-CGI的FastCGI进程

master进程可以理解以下信号

INT, TERM 立刻终止
QUIT 平滑终止
USR1 重新打开日志文件
USR2 平滑重载所有worker进程并重新载入配置和二进制模块

「Swoole也是如此来实现平滑重启的,当然要通过检测文件变化,然后执行平滑重启或重启命令」

示例:

php-fpm 关闭:    
kill -INT `cat /usr/local/php/var/run/php-fpm.pid`

php-fpm 重启:
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`

查看php-fpm进程数:
ps aux | grep -c php-fpm

php-fmp的重启 (方法二)

先执行
killall php-fpm

再执行(usr/local/php是php的安装目录)
/usr/local/php/sbin/php-fpm &

3. Mac下,PHP环境报错

➜  ~ php72 -v

dyld[74083]: Library not loaded: '/opt/homebrew/opt/icu4c/lib/libicui18n.71.dylib'

  Referenced from: '/opt/homebrew/Cellar/php@7.2/7.2.34_5/bin/php'

  Reason: tried: '/opt/homebrew/opt/icu4c/lib/libicui18n.71.dylib' (no such file), '/usr/local/lib/libicui18n.71.dylib' (no such file), '/usr/lib/libicui18n.71.dylib' (no such file), '/opt/homebrew/Cellar/icu4c/70.1/lib/libicui18n.71.dylib' (no such file), '/usr/local/lib/libicui18n.71.dylib' (no such file), '/usr/lib/libicui18n.71.dylib' (no such file)

[1]    74083 abort      /opt/homebrew/opt/php@7.2/bin/php -v

➜  ~

原因应该是brew自动升级导致,但是升级不完全。

解决办法:

How to Fix 'Dyld: Library not Loaded' Error on MacOS - Appuals.com

推荐方案:

brew update // 更新homebrew软件源

brew upgrade // 更新本机上安装的软件

但是这里在更新完之后,

➜  macOS git:(main) php74 -v

zsh: command not found: php74

➜  macOS git:(main)

解决办法:

➜  ~ source .zshrc

➜  ~ php74 -v

PHP 7.4.32 (cli) (built: Sep 29 2022 10:45:51) ( NTS )

Copyright (c) The PHP Group

Zend Engine v3.4.0, Copyright (c) Zend Technologies

    with Zend OPcache v7.4.32, Copyright (c), by Zend Technologies

➜  ~

同时可以看到

➜  ~ php72 -v

PHP 7.2.34 (cli) (built: Sep 29 2022 07:10:27) ( NTS )

Copyright (c) 1997-2018 The PHP Group

Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

    with Zend OPcache v7.2.34, Copyright (c) 1999-2018, by Zend Technologies

➜  ~ php72-fpm -v

PHP 7.2.34 (fpm-fcgi) (built: Sep 29 2022 07:10:29)

Copyright (c) 1997-2018 The PHP Group

Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

    with Zend OPcache v7.2.34, Copyright (c) 1999-2018, by Zend Technologies

➜  ~

php7.2 版本的问题已解决

4.参考

参见上面文档列表

后续补充

...

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值