3.6:Nginx 转发 FastCGI 请求

CGI 和 FastCGI:

CGI,Common Gateway Interface,通用网关接口,Nginx 基于 CGI 协议转发客户端的动态资源请求至 PHP 程序,由这些程序处理完请求后,返回结果给 Nginx,再由 Nginx 返回客户端相应的数据;

早期的 CGI 协议,对于每一个请求都会创建一个 CGI 进程,解析并处理完毕后再关闭进程,效率很低;

FastCGI 处理完请求后,不会立即关闭进程,而是保留并继续处理新的请求,使得不用反复创建新的进程,提升了处理效率;

php-fpm:

FPM,FastCGI Process Manager,FastCGI 进程管理器,提供 FastCGI 进程启动和管理的功能;

FastCGI 的进程运行模式为 master-worker 模式:

  • 一个 master 进程,负责监听并接收来自 web 服务转发的客户端请求;
  • 多个 worker 进程,每个 worker 进程都有一个 PHP 解析器,用于 PHP 代码的解析处理;

Nginx 的 FastCGI 相关功能由 ngx_http_fastcgi_module 模块提供;

3.6.1:准备 PHP 环境

安装 php-fpm
  • yum 安装 php-fpm:
[root@node106 ~]# yum install php-fpm -y
配置 php-fpm
  • php-fpm.conf:

修改 daemonize = yes,设置为后台启动;

[root@node106 ~]# grep -v ';' /etc/php-fpm.conf | grep -v '^$'
include=/etc/php-fpm.d/*.conf
[global]
pid = /run/php-fpm/php-fpm.pid
error_log = /var/log/php-fpm/error.log
daemonize = yes
  • www.conf:
  • 启动 php-fpm worker 进程的用户要和启动 nginx worker 进程的用户一致,因为涉及文件权限问题;
  • 当 php-fpm 和 nginx 不在同一服务器时,需要:
  • 设置 fastcgi 监听在可通信的 IP 地址上,或者直接监听所有地址 listen = 0.0.0.0:9000
  • 注释 listen.allowed_clients = 127.0.0.1,或者设置为相应的 nginx 服务器地址;
  • pm.max_children 的值是在实行进程动态管理(pm = dynamic)时,能够启动的 worker 进程数的最大值;
  • pm.start_servers 的值是在实行进程动态管理(pm = dynamic)时,初始启动的 worker 进程数,所以需要 ≥ pm.min_spare_servers 指定的最小空闲进程数,并 ≤ pm.max_spare_servers 指定的最大空闲进程数;
  • pm.max_requests 的值是单个 worker 进程累计能够处理的最大请求数,当达到这个请求数后,会回收 worker 进程,并重新启动一个 worker 进程;
[root@node106 ~]# grep -v ';' /etc/php-fpm.d/www.conf | grep -v '^[[:space:]]*$'
[www]
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
user = nginx
group = nginx
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 5000
pm.status_path = /pm_status
ping.path = /ping
ping.response = pong
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
启动 php-fpm
  • 启动 php-fpm:
[root@node106 ~]# systemctl start php-fpm
[root@node106 ~]# systemctl enable php-fpm
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.
  • 查看端口:
[root@node106 ~]# ss -tnl | grep 9000
LISTEN     0      128    127.0.0.1:9000                     *:*
准备 PHP 测试页面
  • 创建 php 资源目录及信息页:
[root@node106 ~]# mkdir /data/nginx/yqc/www/php
[root@node106 ~]# vim /data/nginx/yqc/www/php/index.php
<?php
  phpinfo();
?>

3.6.2:Nginx 配置 FastCGI 转发

  • 配置所有以 .php 结尾的 URI 请求,都转发至 php-fpm 进行处理:

定义php资源请求的根目录为 /data/nginx/yqc/www/php;

location ~ \.php$ {
    root /data/nginx/yqc/www/php;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include /apps/nginx/conf/fastcgi_params;
  }
  • 配置php状态页和/ping测试的请求转发:
location ~ ^/(pm_status|ping)$ {
    fastcgi_pass 127.0.0.1;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
    include /apps/nginx/conf/fastcgi_params;
  }
  • 检查配置文件并重载nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# !sys
systemctl reload nginx
  • 访问php信息页:

nginx支持blob媒体文件 nginx支持cgi_php

  • 访问 PHP 状态页和 ping 测试:
[root@node105 ~]# curl http://www.yqc.com/pm_status
pool:                 www
process manager:      dynamic
start time:           05/Dec/2020:16:00:44 +0800
start since:          1071
accepted conn:        9
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       4
active processes:     1
total processes:      5
max active processes: 2
max children reached: 0
slow requests:        0

[root@node105 ~]# curl http://www.yqc.com/ping
pong