• php-fpm详解


    2022年9月27日15:45:04

    FastCGI(Fast Common Gateway Interface)快速通用网关接口,是 CGI 的增强版本,为了提升 CGI 的性能而生。
    PHP-FPM(FastCGI Process Manager for PHP)PHP 的 FastCGI 进程管理器。FastCGI 只是一个协议规范,需要某个程序去具体实现,而 PHP-FPM 就是这个具体实现。

    1. ps -ef|grep php
    2. root 2178 1 0 13:28 ? 00:00:00 php-fpm: master process (/usr/local/php80/etc/php-fpm.conf)
    3. www 2179 2178 0 13:28 ? 00:00:00 php-fpm: pool www
    4. www 2180 2178 0 13:28 ? 00:00:00 php-fpm: pool www
    5. root 2248 1 0 13:29 ? 00:00:00 php-fpm: master process (/usr/local/php74/etc/php-fpm.conf)
    6. www 2250 2248 0 13:29 ? 00:00:00 php-fpm: pool www
    7. www 2251 2248 0 13:29 ? 00:00:00 php-fpm: pool www

    这里可以看到fpm是一个常驻内存的master -> worker的多进程工作模式

    fpm是一个php的工作方式,请注意!

    PHP的SAPI模块 方式目前有以下几种:

    1. CGI(通用网关接口/ Common Gateway Interface)
    2. FastCGI(常驻型CGI / Long-Live CGI)
    3. CLI(命令行运行 / Command Line Interface)
    4. Web模块模式(Apache等Web服务器运行的模式)
    5. ISAPI(Internet Server Application Program Interface)
    6. LSAPI

    强调一下,工作模式和php语言本身实现任何功能基本毫无影响,以上都是通过通信协议互相通信而已

    PHP: php_sapi_name - Manual
    返回接口类型的小写字符串, 或者在失败时返回 false。

    对应的fpm代码的如下:

    1. D:\SRC_CODE\20220824\PHP-SRC_1\SAPI
    2. ├─apache2handler
    3. ├─cgi
    4. │ └─tests
    5. ├─cli
    6. │ └─tests
    7. ├─embed
    8. ├─fpm
    9. │ ├─fpm
    10. │ │ └─events
    11. │ └─tests
    12. ├─fuzzer
    13. │ ├─corpus
    14. │ │ ├─exif
    15. │ │ ├─json
    16. │ │ └─unserialize
    17. │ └─dict
    18. ├─litespeed
    19. └─phpdbg
    20. └─tests
    21. └─bug73615

    fpm自身是什么呢?

    1. PS D:\src_code\20220824\php-src_1\sapi\fpm\fpm\events> ls
    2. 目录: D:\src_code\20220824\php-src_1\sapi\fpm\fpm\events
    3. Mode LastWriteTime Length Name
    4. ---- ------------- ------ ----
    5. -a---- 2022/9/28 14:04 5872 devpoll.c
    6. -a---- 2022/9/28 14:04 1228 devpoll.h
    7. -a---- 2022/9/28 14:04 5192 epoll.c
    8. -a---- 2022/9/28 14:04 1220 epoll.h
    9. -a---- 2022/9/28 14:04 4876 kqueue.c
    10. -a---- 2022/9/28 14:04 1224 kqueue.h
    11. -a---- 2022/9/28 14:04 6465 poll.c
    12. -a---- 2022/9/28 14:04 1216 poll.h
    13. -a---- 2022/9/28 14:04 4931 port.c
    14. -a---- 2022/9/28 14:04 1216 port.h
    15. -a---- 2022/9/28 14:04 4187 select.c
    16. -a---- 2022/9/28 14:04 1224 select.h
    17. PS D:\src_code\20220824\php-src_1\sapi\fpm\fpm> ls
    18. 目录: D:\src_code\20220824\php-src_1\sapi\fpm\fpm
    19. Mode LastWriteTime Length Name
    20. ---- ------------- ------ ----
    21. d----- 2022/9/28 14:04 events
    22. -a---- 2022/9/28 14:04 2966 fpm.c
    23. -a---- 2022/9/28 14:04 1160 fpm.h
    24. -a---- 2022/9/28 14:04 1951 fpm_arrays.h
    25. -a---- 2022/9/28 14:04 4127 fpm_atomic.h
    26. -a---- 2022/9/28 14:04 12090 fpm_children.c
    27. -a---- 2022/9/28 14:04 901 fpm_children.h
    28. ........省略

    fpm是c实现了epoll kqueue poll select的event,的master worker的进程管理器,照理来说不会慢,才对

    为什么大多数会认为fpm会慢,吃内存呢?

    参考:性能-webman手册

    1. php-fpm请求开始初始化一切,请求结束销毁一切的开销
    2. php-fpm每次请求从磁盘读取多个php文件,反复词法语法解析、反复编译成opcode开销
    3. 框架反复创建框架相关类实例及初始化的开销
    4. 框架反复连接断开数据库、redis等开销
    5. nginx/apache自身开销以及与php-fpm通讯开销
    6. fpm是常驻类型,为什么维持worker的运行数量,不会归还内存给系统

    其实主要是因为composer的出现,导致框架的vendor越来越庞大,一个简单laravel web项目vendor

    1. [root@ vendor]# ls -lR| grep "^-" | wc -l
    2. 7066
    3. [root@ vendor]# du -sh
    4. 57M

    每次启动就需要加载57M大小的7K+的文件,消耗很多磁盘IO和创建框架实例,消耗巨大
    就导致laravel这么“重”的框架,访问速度就很慢

    有什么解决办法呢?
    开启opcache
    ops性能提升至少5-10倍左右,可以看下你的php.ini是否开启(api请求,混编的页面性能提升更小)
    php -m
    是否包含Zend OPcache

    设置pm.max_requests=0,就是不归还给系统,你可以把这个设置成pm.max_requests=50,就请求了50个之后,就释放内存给系统
    如果max_requests太小,就会不停的请求内存,释放内存性能有影响
    设置成0,就会不释放内存,造成系统工作内存资源太小,导致系统越来越卡

    如何设置合理的配置呢?
    1,pm = dynamic,这样由fpm自己调整
    2,需要更高性能的ops,根据自己大小简单计算一下,比如4核8G内存,8G至少留1g给系统,php单个变量大小是128M,以此为最大基准,(7*1024)/128 = 56,这里是纯fpm的机器,不包含nginx redis等服务,如果在同一个服务器就扣除其他运行内存

    1. pm = static
    2. pm.max_children = 56
    3. pm.start_servers = 20
    4. pm.max_requests = 200

    这里全部是理论数值

    1. cat /proc/1197/status
    2. cat /proc/$(pid)/status

    查看

    1. VmPeak: 247844 kB
    2. VmSize: 234784 kB ——进程占用的虚拟内存大小
    3. VmLck: 0 kB
    4. VmPin: 0 kB
    5. VmHWM: 34296 kB
    6. VmRSS: 21660 kB ——占用的物理内存 约21M

    通常一个fpm的工作内存是几十M,上诉的设置是很宽松的,但是设置过多的children数量会受cpu的影响,频繁切换cpu上下文的去执行会造成一些性能影响,可以通过观察服务器的访问量,服务器内存和cpu的使用量去了解最适合你业务系统的配置,需要一个过程。

    比如你的业务系统查询多,或者计算多,或者业务系统不同会对fpm设置都会需要微调

    那么避免上述的所有的问题,开发一个常驻内存,不需要频繁加载文件,一个master worker的和其他组件通信可以是常驻内存连接
    的框架,那么php的性能是不是可以有非常大的提升,答案是:完全可以

    一个完全由php开发的常驻内存的mvc框架 基于workerman的webman就是一个很大的php高性能框架,完美的避开了fpm的缺点

    FastCGI的通信协议:

    nginx和fpm通信协议是FastCGI,fpm有两种对接模式,端口和sock

    1. location ~ \.php(.*)$ {
    2. fastcgi_pass unix:/usr/local/php80/php-fpm.sock;
    3. #fastcgi_pass 127.0.0.1:9001;
    4. fastcgi_index index.php;
    5. fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
    6. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    7. fastcgi_param PATH_INFO $fastcgi_path_info;
    8. fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
    9. include fastcgi_params;
    10. }

    如果可以使用sock性能当然是更好的,但是nginx和fpm是分离的监听端口模式会更好一点,因为安全也是一个很大的因素

    workerman也实现了FastCGI协议

    php实现fastcgiGitHub - lisachenko/protocol-fcgi: FastCGI (FCGI) Protocol implementation for PHP
    nginx对接fastcgiPHP FastCGI Example | NGINX
    FastCGI协议标准FastCGI协议规范中文版_文化 & 方法_比克_InfoQ精选文章

    FastCGI Specificationhttps://www.myway5.com/index.php/2018/07/19/fastcgi-规范中文翻译/【PHP源码分析】FastCGI协议浅析_慕课手记
    源码php-src/fastcgi.c at master · php/php-src · GitHub

    如果你想对fastcgi有更多的了解Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写 | 离别歌
    你就会发现,nginx想的配置文件 fastcgi.conf fastcgi_params里面参数的意思

    1. fastcgi_param QUERY_STRING $query_string;
    2. fastcgi_param REQUEST_METHOD $request_method;
    3. fastcgi_param CONTENT_TYPE $content_type;
    4. fastcgi_param CONTENT_LENGTH $content_length;
    5. fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    6. fastcgi_param REQUEST_URI $request_uri;
    7. fastcgi_param DOCUMENT_URI $document_uri;
    8. fastcgi_param DOCUMENT_ROOT $document_root;
    9. fastcgi_param SERVER_PROTOCOL $server_protocol;
    10. fastcgi_param REQUEST_SCHEME $scheme;
    11. fastcgi_param HTTPS $https if_not_empty;
    12. fastcgi_param GATEWAY_INTERFACE CGI/1.1;
    13. fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
    14. fastcgi_param REMOTE_ADDR $remote_addr;
    15. fastcgi_param REMOTE_PORT $remote_port;
    16. fastcgi_param SERVER_ADDR $server_addr;
    17. fastcgi_param SERVER_PORT $server_port;
    18. fastcgi_param SERVER_NAME $server_name;
    19. # PHP only, required if PHP was built with --enable-force-cgi-redirect
    20. fastcgi_param REDIRECT_STATUS 200;

    剩下就是最重要的配置文件,下面是基于php8.0的中文翻译版
    php-fpm.conf

    1. ;;;;;;;;;;;;;;;;;;;;;
    2. ; FPM 配置 ;
    3. ;;;;;;;;;;;;;;;;;;;;;
    4. ; 此配置文件中的所有相对路径都是相对于 PHP 的安装
    5. ; 前缀 (/usr/local/php80)。 这个前缀可以通过使用
    6. ; 命令行中的“-p”参数。
    7. ;;;;;;;;;;;;;;;;;;
    8. ; 全局 选项 ;
    9. ;;;;;;;;;;;;;;;;;;
    10. [global]
    11. ; pid文件
    12. ; 注意:默认前缀是 /usr/local/php80/var
    13. ; 默认值:无
    14. ;pid = 运行/php-fpm.pid
    15. pid = /usr/local/php80/php-fpm.pid
    16. ; 错误日志文件
    17. ; 如果它设置为“syslog”,日志将被发送到 syslogd 而不是被写入
    18. ; 到本地文件中。
    19. ; 注意:默认前缀是 /usr/local/php80/var
    20. ; 默认值:log/php-fpm.log
    21. ;error_log = log/php-fpm.log
    22. error_log = /data/log/php80/php-fpm.log
    23. ; syslog_facility 用于指定什么类型的程序正在记录
    24. ; 信息。 这让 syslogd 指定来自不同设施的消息
    25. ; 会以不同方式处理。
    26. ; 请参阅 syslog(3) 以获取可能的值(例如 daemon equiv LOG_DAEMON)
    27. ; 默认值:daemon
    28. ;syslog.facility = daemon
    29. ; syslog_ident 附加在每条消息之前。 如果您有多个 FPM
    30. ; 在同一台服务器上运行的实例,您可以更改默认值
    31. ; 这必须满足共同的需求。
    32. ; 默认值:php-fpm
    33. ;syslog.ident = php-fpm
    34. ; 日志级别
    35. ; 可能的值:alert, error, warning, notice, debug
    36. ; 默认值: notice
    37. ;log_level = notice
    38. ; 单行中字符数的日志限制(日志条目)。 如果
    39. ; 行超过限制,它被包裹在多行上。 限制是为了
    40. ; 所有记录的字符,包括消息前缀和后缀(如果存在)。 然而
    41. ; 换行符不计入其中,因为它仅在
    42. ; 记录到文件描述符。 这意味着新行字符不存在
    43. ; 登录到系统日志时。
    44. ; 默认值: 1024
    45. ;log_limit = 4096
    46. ; 日志缓冲指定日志行是否被缓冲,这意味着
    47. ; 行在单个写入操作中写入。 如果该值为 false,则
    48. ; 数据直接写入文件描述符。 这是一个实验
    49. ; 可以潜在地提高日志记录性能和内存使用的选项
    50. ; 对于一些繁重的日志记录场景。 如果记录到 syslog,则忽略此选项
    51. ; 因为它必须始终被缓冲。
    52. ; 默认值: yes
    53. ;log_buffering = no
    54. ; 如果此数量的子进程在此时间内以 SIGSEGV 或 SIGBUS 退出
    55. ; 由 Emergency_restart_interval 设置的时间间隔,然后 FPM 将重新启动。 一个值
    56. ; “0”表示“关闭”。
    57. ; 默认值: 0
    58. ;emergency_restart_threshold = 0
    59. ; Emergency_restart_interval 使用的时间间隔来确定何时
    60. ; 将启动正常重启。 这对于解决问题很有用
    61. ; 加速器共享内存中的意外损坏。
    62. ; 可用单位:s(秒)、m(整数)、h(我们的)或 d(ays)
    63. ; 默认单位:秒
    64. ; 默认值: 0
    65. ;emergency_restart_interval = 0
    66. ; 子进程等待主进程对信号做出反应的时间限制。
    67. ; 可用单位:s(秒)、m(整数)、h(我们的)或 d(ays)
    68. ; 默认单位:秒
    69. ; 默认值:0
    70. ;process_control_timeout = 0
    71. ; FPM 将分叉的最大进程数。 这是为了控制
    72. ; 在许多池中使用动态 PM 时的全局进程数。
    73. ; 谨慎使用。
    74. ; 注意:值为 0 表示没有限制
    75. ; 默认值:0
    76. ; process.max = 128
    77. ; 指定 nice(2) 优先级以应用于主进程(仅当设置时)
    78. ; 该值可以从 -19(最高优先级)到 20(最低优先级)变化
    79. ; 注意: - 仅当 FPM 主进程以 root 身份启动时才有效
    80. ; - 池进程将继承主进程优先级
    81. ; 除非另有说明
    82. ; 默认值: no set
    83. ; process.priority = -19
    84. ; 将 FPM 发送到后台。 设置为“否”以将 FPM 保持在前台进行调试。
    85. ; 默认值: yes
    86. ;daemonize = yes
    87. ; 为主进程设置打开文件描述符 rlimit。
    88. ; 默认值: system defined value
    89. ;rlimit_files = 1024
    90. ; 为主进程设置最大核心大小 rlimit。
    91. ; 可能的值:“无限”或大于或等于 0 的整数
    92. ; 默认值: system defined value
    93. ;rlimit_core = 0
    94. ; 指定 FPM 将使用的事件机制。 以下是可用的:
    95. ; - select (any POSIX os)
    96. ; - poll (any POSIX os)
    97. ; - epoll (linux >= 2.5.44)
    98. ; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)
    99. ; - /dev/poll (Solaris >= 7)
    100. ; - port (Solaris >= 10)
    101. ; Default Value: not set (auto detection)
    102. ;events.mechanism = epoll
    103. ; 当 FPM 使用 systemd 集成构建时,指定间隔,
    104. ; 在几秒钟内,在向 systemd 的健康报告通知之间。
    105. ; 设置为 0 以禁用。
    106. ; 可用单位:s(秒)、m(整数)、h(我们的)
    107. ; 默认单位:秒
    108. ; 默认值: 10
    109. ;systemd_interval = 10
    110. ;;;;;;;;;;;;;;;;;;;;
    111. ; 线程池定义 ;
    112. ;;;;;;;;;;;;;;;;;;;;
    113. ; 可以使用不同的侦听方式启动多个子进程池
    114. ; 端口和不同的管理选项。 池的名称将是
    115. ; 用于日志和统计信息。 池的数量没有限制
    116. ; FPM可以处理。 无论如何,您的系统会告诉您:)
    117. ; 包括一个或多个文件。 如果 glob(3) 存在,它用于包含一堆
    118. ; 来自 glob(3) 模式的文件。 该指令可以在任何地方使用
    119. ; 文件。
    120. ; 也可以使用相对路径。 它们的前缀为:
    121. ; - 全局前缀(如果已设置)(-p 参数)
    122. ; - /usr/local/php80 otherwise
    123. include=/usr/local/php80/etc/php-fpm.d/*.conf

    www.conf

    1. ; 启动一个名为“www”的新池。
    2. ; 变量 $pool 可以在任何指令中使用,并将被替换为
    3. ; 池名称(此处为“www”)
    4. [www]
    5. ; 每个池前缀
    6. ; 它仅适用于以下指令:
    7. ; - 'access.log'
    8. ; - 'slowlog'
    9. ; - 'listen' (unixsocket)
    10. ; - 'chroot'
    11. ; - 'chdir'
    12. ; - 'php_values'
    13. ; - 'php_admin_values'
    14. ; 如果未设置,则应用全局前缀(或 /usr/local/php80)。
    15. ; 注意:该指令也可以相对于全局前缀。
    16. ; 默认值: none
    17. ;prefix = /path/to/pools/$pool
    18. ; Unix 用户/进程组
    19. ; 注意:用户是强制性的。 如果未设置组,则默认用户的组
    20. ; 将会被使用。
    21. user = www
    22. group = www
    23. ; 接受 FastCGI 请求的地址。
    24. ; 有效的语法是:
    25. ; 'ip.add.re.ss:port' - 在 TCP 套接字上侦听特定 IPv4 地址
    26. ; 特定端口;
    27. ; '[ip:6:addr:ess]:port' - 在 TCP 套接字上监听特定 IPv6 地址
    28. ; 特定端口;
    29. ; 'port' - 在 TCP 套接字上侦听所有地址
    30. ; (IPv6 和 IPv4 映射)在特定端口上;
    31. ; '/path/to/unix/socket' - 监听 unix 套接字。
    32. ; 注意:此值是强制性的。
    33. ;listen = 127.0.0.1:9000
    34. listen = /usr/local/php80/php-fpm.sock
    35. ; 设置listen(2) 积压的任务。
    36. ; 默认值:511(FreeBSD 和 OpenBSD 上为 -1)
    37. ;listen.backlog = 511
    38. ; 设置 unix 套接字的权限,如果使用的话。 在 Linux 中,读/
    39. ; 必须设置权限才能允许来自 Web 服务器的连接。 许多
    40. ; BSD 派生系统允许连接而不管权限。 主人
    41. ; 和组可以通过名称或它们的数字 ID 来指定。
    42. ; 默认值:用户和组设置为运行用户
    43. ; 模式设置为 0660
    44. listen.owner = www
    45. listen.group = www
    46. listen.mode = 0660
    47. ; 当支持 POSIX 访问控制列表时,您可以使用
    48. ; 在这些选项中,value 是用户/组名称的逗号分隔列表。
    49. ; 设置后,listen.owner 和 listen.group 将被忽略
    50. ;listen.acl_users =
    51. ;listen.acl_groups =
    52. ; 允许连接的 FastCGI 客户端的地址列表(IPv4/IPv6)。
    53. ; 相当于原来的FCGI_WEB_SERVER_ADDRS环境变量
    54. ; PHP FCGI (5.2.2+)。 仅对 tcp 侦听套接字才有意义。 每个地址
    55. ; 必须用逗号分隔。 如果此值留空,则连接将是
    56. ; 从任何 IP 地址接受。
    57. ; 默认值: any
    58. ;listen.allowed_clients = 127.0.0.1
    59. ; 指定 nice(2) 优先级以应用于池进程(仅当设置时)
    60. ; 该值可以从 -19(最高优先级)到 20(较低优先级)变化
    61. ; 注意: - 仅当 FPM 主进程以 root 身份启动时才有效
    62. ; - 池进程将继承主进程优先级
    63. ; 除非另有说明
    64. ; 默认值: no set
    65. ; process.priority = -19
    66. ; 设置进程可转储标志 (PR_SET_DUMPABLE prctl) 即使进程用户
    67. ; 或组不同于主进程用户。 它允许创建进程
    68. ; 池用户的核心转储和 ptrace 进程。
    69. ; 默认值: no
    70. ; process.dumpable = yes
    71. ;选择进程管理器将如何控制子进程的数量。
    72. ;可能的值:
    73. ; static - 固定数量(pm.max_children)的子进程;
    74. ; dynamic - 子进程的数量是根据以下指令动态设置的。 使用此流程管理,将始终至少有
    75. ; 1 个子进程。
    76. ; pm.max_children - 可以同时存活的子进程的最大数量
    77. ; pm.start_servers - 启动子进程的数量.
    78. ; pm.min_spare_servers - 处于“空闲”状态(等待处理)的最小孩子数。 ;
    79. ; 如果 “空闲”进程的数量少于此数量,则将创建一些子进程。
    80. ; pm.max_spare_servers - 处于“空闲”状态的最大子节点数(等待处理)。
    81. ; 如果“空闲”进程的数量大于这个数量,那么一些子进程将被杀死。
    82. ; ondemand - 启动时不创建子级。当新请求连接时,子进程才会被forked创建.使用以下参数:
    83. ; pm.max_children - 可以同时活着的子进程的最大数量。
    84. ; pm.process_idle_timeout - 空闲进程将被终止的秒数。
    85. ;注意:此值是强制性的。
    86. pm = dynamic
    87. ; 当 pm 设置为 'static'
    88. ; pm 设置为“动态”或“按需”时的最大子进程数。
    89. ; 此值设置将同时请求的数量限制
    90. ; 服务。 等效于带有 mpm_prefork 的 ApacheMaxClients 指令。
    91. ; 等效于原始 PHP 中的 PHP_FCGI_CHILDREN 环境变量
    92. ; 电脑动画。 以下默认值基于没有太多资源的服务器。 别
    93. ; 忘记调整 pm.* 以满足您的需求。
    94. ; 注意:当 pm 设置为“静态”、“动态”或“按需”时使用
    95. ; 注意:此值是强制性的。
    96. pm.max_children = 20
    97. ; 启动时创建的子进程数。
    98. ; 注意:仅在 pm 设置为“动态”时使用
    99. ; 默认值:(min_spare_servers + max_spare_servers) / 2
    100. pm.start_servers = 2
    101. ; 所需的最小空闲服务器进程数。
    102. ; 注意:仅在 pm 设置为“动态”时使用
    103. ; 注意:当 pm 设置为“动态”时为必填项
    104. pm.min_spare_servers = 1
    105. ; 所需的最大空闲服务器进程数。
    106. ; 注意:仅在 pm 设置为“动态”时使用
    107. ; 注意:当 pm 设置为“动态”时为必填项
    108. pm.max_spare_servers = 3
    109. ; 空闲进程将被杀死的秒数。
    110. ; 注意:仅在 pm 设置为 'ondemand' 时使用
    111. ; 默认值: 10s
    112. ;pm.process_idle_timeout = 10s;
    113. ; 每个子进程在重生之前应执行的请求数。
    114. ; 这对于解决 3rd 方库中的内存泄漏问题很有用。 为了
    115. ; 无休止的请求处理指定“0”。 等效于 PHP_FCGI_MAX_REQUESTS。
    116. ; 默认值: 0
    117. pm.max_requests = 200
    118. ; 查看 FPM 状态页面的 URI。 如果未设置此值,则不会有 URI
    119. ; 识别为状态页面。 它显示以下信息:
    120. ; pool - 池的名称
    121. ; process manager - static, dynamic or ondemand;
    122. ; start time - FPM 开始的日期和时间;
    123. ; start since - 自 FPM 开始以来的秒数;
    124. ; accepted conn - 池接受的请求数;
    125. ; listen queue - 待处理队列中的请求数 连接(参见listen(2)中的积压任务);
    126. ; max listen queue - 自 FPM 启动以来,待处理连接队列中的最大请求数
    127. ; listen queue len - 挂起连接的套接字队列的大小;
    128. ; idle processes - 空闲进程的数量;
    129. ; active processes - 活动进程的数量;
    130. ; total processes - 空闲+活动进程的数量;
    131. ; max active processes - 自 FPM 启动以来的最大活动进程数;
    132. ; max children reached - 当 pm 尝试启动更多子进程时,已达到进程限制的次数(仅适用于
    133. ; pm 'dynamic''ondemand');
    134. ; 值实时更新。
    135. ; Example output:
    136. ; pool: www
    137. ; process manager: static
    138. ; start time: 01/Jul/2011:17:53:49 +0200
    139. ; start since: 62636
    140. ; accepted conn: 190460
    141. ; listen queue: 0
    142. ; max listen queue: 1
    143. ; listen queue len: 42
    144. ; idle processes: 4
    145. ; active processes: 11
    146. ; total processes: 15
    147. ; max active processes: 12
    148. ; max children reached: 0
    149. ;
    150. ; 默认情况下,状态页面输出格式为 text/plain。 通过任一
    151. ; 查询字符串中的'html''xml''json'会返回对应的
    152. ; output syntax. Example:
    153. ; http://www.foo.bar/status
    154. ; http://www.foo.bar/status?json
    155. ; http://www.foo.bar/status?html
    156. ; http://www.foo.bar/status?xml
    157. ;
    158. ; 默认情况下,状态页面只输出简短的状态。 传递“完整”
    159. ; 查询字符串还将返回每个池进程的状态。
    160. ; Example:
    161. ; http://www.foo.bar/status?full
    162. ; http://www.foo.bar/status?json&full
    163. ; http://www.foo.bar/status?html&full
    164. ; http://www.foo.bar/status?xml&full
    165. ; 每个进程的完整状态返回:
    166. ; pid - 进程的PID;
    167. ; state - 进程的状态(空闲,运行,...);
    168. ; start time - 流程开始的日期和时间;
    169. ; start since - 自进程开始以来的秒数;
    170. ; requests - 进程已处理的请求数;
    171. ; request duration - 请求的持续时间(以 µs 为单位);
    172. ; request method - 请求方法(GET,POST,...);
    173. ; request URI - 带有查询字符串的请求 URI;
    174. ; content length - 请求的内容长度(仅限 POST)
    175. ; user - 用户(PHP_AUTH_USER)(如果未设置,则为“-”);
    176. ; script - 调用的主脚本(如果未设置,则为“-”);
    177. ; last request cpu - 如果进程未处于空闲状态,则最后一个请求消耗的 %cpu 始终为 0
    178. ; 因为 CPU 计算是在请求处理终止时完成的;
    179. ; last request memory - 最后一个请求消耗的最大内存量,如果进程不处于空闲状态,
    180. ; 则它始终为 0,因为在请求处理终止时完成了内存计算;
    181. ; 如果进程处于空闲状态,则信息与
    182. ; 进程服务的最后一个请求。 否则信息与
    183. ; 当前正在处理的请求。
    184. ; Example output:
    185. ; ************************
    186. ; pid: 31330
    187. ; state: Running
    188. ; start time: 01/Jul/2011:17:53:49 +0200
    189. ; start since: 63087
    190. ; requests: 12808
    191. ; request duration: 1250261
    192. ; request method: GET
    193. ; request URI: /test_mem.php?N=10000
    194. ; content length: 0
    195. ; user: -
    196. ; script: /home/fat/web/docs/php/test_mem.php
    197. ; last request cpu: 0.00
    198. ; last request memory: 0
    199. ;
    200. ; 注意:有一个实时 FPM 状态监控示例网页可用
    201. ; 它位于:/usr/local/php80/share/php/fpm/status.html
    202. ;
    203. ; 注意:该值必须以斜杠 (/) 开头。 该值可以是
    204. ; 任何东西,但使用 .php 扩展名或它可能不是一个好主意
    205. ; 可能与真实的 PHP 文件冲突。
    206. ; 默认值: not set
    207. ;pm.status_path = /status
    208. ; 接受 FastCGI 状态请求的地址。 这创造了一个新的
    209. ; 可以独立处理请求的隐形池。 这很有用
    210. ; 如果主池忙于长时间运行的请求,因为它仍然可能
    211. ; 在完成长时间运行的请求之前获取状态。
    212. ;
    213. ; 有效的语法是:
    214. ; 'ip.add.re.ss:port' - 在 TCP 套接字上侦听特定端口上的特定 IPv4 地址;
    215. ; '[ip:6:addr:ess]:port' - 在 TCP 套接字上侦听特定端口上的特定 IPv6 地址;
    216. ; 'port' - 在 TCP 套接字上侦听特定端口上的所有地址(IPv6和IPv4 映射);
    217. ; '/path/to/unix/socket' - 在 Unix 套接字上监听。
    218. ; 默认值: value of the listen option
    219. ;pm.status_listen = 127.0.0.1:9001
    220. ; 调用FPM监控页面的ping URI。 如果未设置此值,则否
    221. ; URI 将被识别为 ping 页面。 这可以用来从外部测试
    222. ; FPM 是活跃的并且正在响应,或者
    223. ; - 创建 FPM 可用性图表(rrd 等);
    224. ; - 如果服务器没有响应(负载平衡),则从组中删除它;
    225. ; - 为运营团队触发警报 (24/7)。
    226. ; 注意:该值必须以斜杠 (/) 开头。 该值可以是
    227. ; 任何东西,但使用 .php 扩展名或它可能不是一个好主意
    228. ; 可能与真实的 PHP 文件冲突。
    229. ; 默认值: not set
    230. ;ping.path = /ping
    231. ; 该指令可用于自定义 ping 请求的响应。 这
    232. ; 响应格式为文本/纯文本,响应代码为 200
    233. ; 默认值: pong
    234. ;ping.response = pong
    235. ; 访问日志文件
    236. ; Default: not set
    237. ;access.log = log/$pool.access.log
    238. ; 访问日志格式。
    239. ; 允许使用以下语法
    240. ; %%: the '%' character
    241. ; %C: %CPU used by the request
    242. ; it can accept the following format:
    243. ; - %{user}C for user CPU only
    244. ; - %{system}C for system CPU only
    245. ; - %{total}C for user + system CPU (default)
    246. ; %d: time taken to serve the request
    247. ; it can accept the following format:
    248. ; - %{seconds}d (default)
    249. ; - %{milliseconds}d
    250. ; - %{mili}d
    251. ; - %{microseconds}d
    252. ; - %{micro}d
    253. ; %e: an environment variable (same as $_ENV or $_SERVER)
    254. ; it must be associated with embraces to specify the name of the env
    255. ; variable. Some examples:
    256. ; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
    257. ; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
    258. ; %f: script filename
    259. ; %l: content-length of the request (for POST request only)
    260. ; %m: request method
    261. ; %M: peak of memory allocated by PHP
    262. ; it can accept the following format:
    263. ; - %{bytes}M (default)
    264. ; - %{kilobytes}M
    265. ; - %{kilo}M
    266. ; - %{megabytes}M
    267. ; - %{mega}M
    268. ; %n: pool name
    269. ; %o: output header
    270. ; it must be associated with embraces to specify the name of the header:
    271. ; - %{Content-Type}o
    272. ; - %{X-Powered-By}o
    273. ; - %{Transfert-Encoding}o
    274. ; - ....
    275. ; %p: PID of the child that serviced the request
    276. ; %P: PID of the parent of the child that serviced the request
    277. ; %q: the query string
    278. ; %Q: the '?' character if query string exists
    279. ; %r: the request URI (without the query string, see %q and %Q)
    280. ; %R: remote IP address
    281. ; %s: status (response code)
    282. ; %t: server time the request was received
    283. ; it can accept a strftime(3) format:
    284. ; %d/%b/%Y:%H:%M:%S %z (default)
    285. ; The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
    286. ; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t
    287. ; %T: time the log has been written (the request has finished)
    288. ; it can accept a strftime(3) format:
    289. ; %d/%b/%Y:%H:%M:%S %z (default)
    290. ; The strftime(3) format must be encapsuled in a %{<strftime_format>}t tag
    291. ; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t
    292. ; %u: remote user
    293. ;
    294. ; Default: "%R - %u %t \"%m %r\" %s"
    295. ;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
    296. ; 慢请求的日志文件
    297. ; 默认值:未设置
    298. ; 注意:如果设置了 request_slowlog_timeout,slowlog 是强制性的
    299. ;slowlog = log/$pool.log.slow
    300. slowlog = /data/log/php80/slow.log
    301. ; 服务单个请求的超时时间,之后 PHP 回溯将是
    302. ; 转储到“慢日志”文件。 值“0s”表示“关闭”。
    303. ; 可用单位:s(econds)(默认)、m(inutes)、h(ours) 或 d(ays)
    304. ; 默认值: 0
    305. ;request_slowlog_timeout = 0
    306. ; 慢日志堆栈跟踪的深度。
    307. ; 默认值: 20
    308. ;request_slowlog_trace_depth = 20
    309. ; 服务单个请求的超时时间,之后工作进程将
    310. ; 被杀。 当 'max_execution_time' ini 选项时应使用此选项
    311. ; 由于某种原因不会停止脚本执行。 值“0”表示“关闭”。
    312. ; 可用单位:s(econds)(默认)、m(inutes)、h(ours) 或 d(ays)
    313. ; 默认值: 0
    314. ;request_terminate_timeout = 0
    315. ; 'request_terminate_timeout' ini 选项设置的超时后未使用
    316. ; 应用程序调用“fastcgi_finish_request”或应用程序完成时
    317. ; 正在调用关闭函数(通过 register_shutdown_function 注册)。
    318. ; 此选项将启用无条件应用超时限制
    319. ; 即使在这种情况下。
    320. ; 默认值: no
    321. ;request_terminate_timeout_track_finished = no
    322. ; 设置打开文件描述符 rlimit。
    323. ; 默认值: system defined value
    324. ;rlimit_files = 1024
    325. ; 设置最大核心尺寸 rlimit。
    326. ; 可能的值:“无限”或大于或等于 0 的整数
    327. ; 默认值: system defined value
    328. ;rlimit_core = 0
    329. ; chroot 到这个目录开始。 该值必须定义为
    330. ; 绝对路径。 如果未设置此值,则不使用 chroot。
    331. ; 注意:您可以使用 '$prefix' 作为前缀来 chroot 到池前缀或一个
    332. ; 的子目录。 如果未设置池前缀,则使用全局前缀
    333. ; 将被使用。
    334. ; 注意:chrooting 是一个很好的安全功能,应该在任何时候使用
    335. ; 可能的。 但是,所有 PHP 路径都将相对于 chroot
    336. ; (error_log,sessions.save_path,...)。
    337. ; 默认值: not set
    338. ;chroot =
    339. ; chdir 到这个目录开始。
    340. ; 注意:可以使用相对路径。
    341. ; 默认值: current directory or / when chroot
    342. ;chdir = /var/www
    343. ; 将工作人员标准输出和标准错误重定向到主错误日志。 如果未设置,stdout 和
    344. ; 根据 FastCGI 规范,stderr 将被重定向到 /dev/null
    345. ; 注意:在高负载环境下,这可能会导致页面延迟
    346. ; 处理时间(几毫秒)。
    347. ; 默认值: no
    348. ;catch_workers_output = yes
    349. ; 使用包含有关信息的前缀和后缀装饰工作人员输出
    350. ; 写入日志的孩子以及是否使用了 stdout 或 stderr
    351. ; 日志级别和时间。 仅当 catch_workers_output 为 yes 时才使用此选项。
    352. ; 设置为“no”将输出写入 stdout 或 stderr 的数据。
    353. ; 默认值: yes
    354. ;decorate_workers_output = no
    355. ; FPM 工作人员的清晰环境
    356. ; 防止任意环境变量到达 FPM 工作进程
    357. ; 通过在此指定的环境变量之前清除工作人员中的环境
    358. ; 添加池配置。
    359. ; 设置为“no”将使所有环境变量都可用于 PHP 代码
    360. ; 通过 getenv()、$_ENV 和 $_SERVER。
    361. ; 默认值: yes
    362. ;clear_env = no
    363. ; 限制 FPM 允许解析的主脚本的扩展。 这个可以
    364. ; 防止Web服务器端的配置错误。 你应该只限制
    365. ; FPM转.php扩展名,防止恶意用户使用其他扩展名
    366. ; 执行php代码。
    367. ; 注意:设置一个空值以允许所有扩展。
    368. ; 默认值: .php
    369. ;security.limit_extensions = .php .php3 .php4 .php5 .php7
    370. ; 传递环境变量,如 LD_LIBRARY_PATH。 所有 $VARIABLEs 都取自
    371. ; 当前环境。
    372. ; 默认值: clean env
    373. ;env[HOSTNAME] = $HOSTNAME
    374. ;env[PATH] = /usr/local/bin:/usr/bin:/bin
    375. ;env[TMP] = /tmp
    376. ;env[TMPDIR] = /tmp
    377. ;env[TEMP] = /tmp
    378. ; 附加的 php.ini 定义,特定于这个工人池。 这些设置
    379. ; 覆盖之前在 php.ini 中定义的值。 这些指令是
    380. ; 与 PHP SAPI 相同:
    381. ; php_value/php_flag - 您可以设置可以从 PHP 调用 'ini_set' 覆盖的经典 ini 定义。
    382. ; php_admin_value/php_admin_flag - 这些指令不会被 PHP 调用 'ini_set' 覆盖
    383. ; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
    384. ; 定义“扩展”将加载相应的共享扩展
    385. ; 扩展目录。 定义 'disable_functions''disable_classes' 不会
    386. ; 覆盖以前定义的 php.ini 值,但会附加新值
    387. ; 反而。
    388. ; 注意:路径 INI 选项可以是相对的,并且将使用前缀进行扩展
    389. ; (pool, global or /usr/local/php80)
    390. ; 默认值:除了 php.ini 和
    391. ; 在启动时使用 -d 参数指定
    392. ;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
    393. ;php_flag[display_errors] = off
    394. ;php_admin_value[error_log] = /var/log/fpm-php.www.log
    395. ;php_admin_flag[log_errors] = on
    396. ;php_admin_value[memory_limit] = 32M

    最后谈几点关于配置fpm的线程池的问题:

    1. pm的配置模式是 static dynamic ondemand哪个最好,是根据你的业务模式需求来定,你可以通过fpm的slowlog,access.log /status 来判断那种适合你的业务系统,比如查询多的业务,需要大量计算,比如需要很多其他组件通信有延迟的,各种各样的业务,通过不断尝试选择最适合自己的
    2. 有没有最优解? 没有最优解,只能建议:static适合大并发,整体请求平稳的,dynamic适合请求变化大,但是总体请求并不大,ondemand适合对fpm并不清楚怎么配置,最简单
    3. fpm配合opcache使用性能并不差,慢的原因多半是因为框架本身很重
  • 相关阅读:
    【首因效应】第一印象
    如何让Java的线程池顺序执行任务?
    ACM笔记
    【JavaEE】JavaScript(WebAPI)
    35岁的腾讯测试员退休?答:存够2千万回家买房
    第七届 Sky Hackathon 笔记集合贴
    黑客(网络安全)技术自学30天
    学个Antenna:手机天线入门
    结构体内存对齐
    Docker中仓库、镜像和容器用法详解
  • 原文地址:https://blog.csdn.net/zh7314/article/details/127127205