nginx + php-fpm 性能调优

2022-06-27 12:33:30 浏览数 (1)

1. 概述

对于PHP服务而言,nginx php-fpm 是常用的服务配置,如何进行服务器性能调优是一个服务端开发的必备技能。

2. nginx 与 PHP-FPM 的通信

nginx 是通过 fastcgi 与 php-fpm 通信的,他的连接是通过 socket 的方式实现的。 在安装 php-fpm 后,默认他监听了 localhost:9000 的 TCP 端口。 TCP 连接的通信效率要比 UNIX 域协议的通信效率低很多,因此,我们首先通过配置将 nginx 与 php-fpm 的通信改为 UNIX 域协议,可以实现优化。

2.1. nginx 配置

代码语言:javascript复制
location ~ .*.(php|php5)?$ {
    root           /var/www;
    fastcgi_pass   unix:/dev/shm/php-cgi.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME /var/www$fastcgi_script_name;
    include        fastcgi_params;
}

2.2. php-fpm 配置

代码语言:javascript复制
listen = /dev/shm/php-cgi.sock

顺次重启 php-fpm 和 nginx 就实现了通信。

也许你会发现访问返回了 502 bad gate way。 这是因为 unix 域协议文件没有权限访问,可以通过 chmod 改变 /dev/shm/php-cgi.sock 文件的权限解决。

3. nginx worker 数

通过 nginx 配置中的 worker_processes 可以指定 nginx 运行时的 worker 数量,默认在运行 ./configure 的时候会检测硬件将该配置设为 CPU 核心数。 理论上说,worker 越多,处理请求的能力越强,由于 worker_cpu_affinity 将 nginx 的 worker 与 CPU 核心绑定执行,这使得 worker 可以使用 CPU 缓存,避免了上下文切换带来的开销,因此,不要让 worker 数小于 CPU 核心数是最起码的要求,否则多个核心切换时会带来不必要的开销。 测试结果表明,nginx worker 数是 CPU 核心数的 2 倍时性能最优。

4. backlog 的设置

大量并发的场景中,常常会出现 nginx 返回: connect() to unix:/tmp/php-fpm.socket failed (11: Resource temporarily unavailable) while connecting to upstream。 这意味着 php-fpm 停止停止接收任务了。 避免这个问题,就要在 php-fpm 的配置上着手了。

首先,通过调整 nginx、php-fpm 和系统内核的 backlog,可以让 socket 通信积压更大,从而缓解这个压力。 如在 nginx server 块配置中加入:

代码语言:javascript复制
listen 80 default backlog=1024;

在 php-fpm 配置中加入:

代码语言:javascript复制
listen.backlog = 2048

并将 /etc/sysctl.conf 文件中相关配置改为:

代码语言:javascript复制
net.ipv4.tcp_max_syn_backlog = 4096
net.core.netdev_max_backlog = 4096

5. 增加 PHP-FPM worker 数

关于 php-fpm 的 worker 数,有如下四个参数:

  • pm.max_children — 静态方式下开启的 php-fpm 进程数量
  • pm.start_servers — 动态方式下的起始 php-fpm 进程数量
  • pm.min_spare_servers — 动态方式下的最小 php-fpm 进程数量
  • pm.max_spare_servers — 动态方式下的最大 php-fpm 进程数量

通过制定 pm 参数为 static 或 dynamic,php-fpm 会应用上述对应的配置数。 通过将 php-fpm 的 worker 数设置增大,可以增加他的并发能力。 长期运行中,每个 php-fpm worker 占用内存约 30MB 左右,worker 数的具体大小需要根据系统的内存总量控制,否则可能造成系统被拖垮。

6. 定时重启 php-fpm

与 Apache 一样,php-fpm 也有内存泄露的问题,因此定时重启也可以增加系统的性能。 在 crontab 中写入定时的 php-fpm restart 或 reload 是一个很方便的措施。

7. 配置 php-fpm 关闭执行时间限制

通过 php-fpm 配置:

代码语言:javascript复制
request_terminate_timeout = 0

去除 PHP 执行时间限制,不会在 PHP 执行过程中由于超时中止 PHP 的执行。 同时,需要对 PHP 的 max_execution_time 选项进行设置。

8. 配置 php-fpm 查看返回错误

通过 php-fpm 配置:

代码语言:javascript复制
catch_workers_output = yes

这个配置将运行中的 stdout 和 stderr 输出到主要的错误日志文件中。 如果没有设置这个选项,stdout 和 stderr 会被重定向到 /dev/null。

0 人点赞