好的,现在开始我们的PHP-FPM与Nginx配置调优讲座。今天我们将深入探讨如何通过优化FastCGI参数、缓冲区大小和Gzip压缩设置,来提升PHP-FPM与Nginx组合的性能。
一、FastCGI参数调优:连接Nginx与PHP-FPM的桥梁
FastCGI参数是Nginx与PHP-FPM之间通信的关键,合理的配置可以显著提升性能和安全性。
-
fastcgi_pass: 指定PHP-FPM监听的地址和端口。-
Unix Domain Socket: 建议使用,因为它避免了网络开销,速度更快。
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # 根据你的PHP版本调整 -
TCP Socket: 如果PHP-FPM和Nginx不在同一台服务器,则需要使用TCP Socket。
fastcgi_pass 127.0.0.1:9000;
-
-
fastcgi_index: 指定默认的PHP文件。通常是index.php。fastcgi_index index.php; -
fastcgi_param: 设置传递给PHP-FPM的参数。以下是一些重要的参数:SCRIPT_FILENAME: 指定PHP脚本的完整路径。SCRIPT_NAME: 指定PHP脚本相对于网站根目录的路径。REQUEST_URI: 客户端请求的URI。DOCUMENT_ROOT: 网站的根目录。QUERY_STRING: URL中的查询字符串。REQUEST_METHOD: HTTP请求方法(GET、POST等)。CONTENT_TYPE: HTTP请求的Content-Type。CONTENT_LENGTH: HTTP请求的Content-Length。
一个典型的
fastcgi_param配置如下:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; -
fastcgi_read_timeout: 设置Nginx等待PHP-FPM响应的超时时间。 如果PHP脚本执行时间过长,可能会导致504 Gateway Timeout错误。 增加此值可以解决这类问题,但同时也意味着Nginx会等待更长时间。fastcgi_read_timeout 300; # 单位:秒 -
fastcgi_connect_timeout: 设置Nginx连接到PHP-FPM的超时时间。fastcgi_connect_timeout 60; #单位:秒 -
fastcgi_send_timeout: 设置Nginx向PHP-FPM发送请求的超时时间。fastcgi_send_timeout 60; #单位:秒 -
fastcgi_buffersandfastcgi_buffer_size: 控制Nginx用于读取PHP-FPM响应的缓冲区大小。fastcgi_buffers: 设置用于读取PHP-FPM响应的缓冲区的数量和大小。 例如,fastcgi_buffers 16 4k表示使用16个4KB的缓冲区。fastcgi_buffer_size: 设置单个缓冲区的大小。
合理的缓冲区大小可以避免频繁的磁盘I/O,提升性能。 通常,
fastcgi_buffer_size可以设置为页面大小(例如,4KB或8KB),而fastcgi_buffers的数量可以根据应用程序的响应大小进行调整。 如果Nginx错误日志中出现 "upstream sent too big header" 错误,则需要增加fastcgi_buffer_size。fastcgi_buffers 16 16k; fastcgi_buffer_size 16k; -
fastcgi_cacheandfastcgi_cache_valid: 启用FastCGI缓存。 可以将PHP脚本的响应缓存到磁盘上,以减少PHP-FPM的负载。 适用于静态内容或不经常更新的内容。fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=php_cache:10m inactive=60m max_size=1g; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_valid 200 302 60m; fastcgi_cache_valid 301 1h; fastcgi_cache_valid any 1m; fastcgi_cache php_cache; add_header X-Cache $upstream_cache_status;fastcgi_cache_path: 指定缓存目录、缓存级别、缓存区域名称、非活跃时间、最大缓存大小。fastcgi_cache_key: 定义缓存Key的生成方式。fastcgi_cache_valid: 指定不同HTTP状态码的缓存时间。fastcgi_cache: 启用缓存区域。add_header X-Cache: 添加一个HTTP头,显示缓存状态 (HIT, MISS, BYPASS, EXPIRED, STALE)。
注意: 启用FastCGI缓存前,需要创建缓存目录,并设置正确的权限。
mkdir -p /tmp/nginx_cache; chown nginx:nginx /tmp/nginx_cache(假设Nginx运行用户为nginx) -
fastcgi_cache_bypassandfastcgi_no_cache: 控制FastCGI缓存的绕过和禁用。 可以根据请求的Cookie、Header等信息,动态地绕过或禁用缓存。 例如,对于登录用户,可以禁用缓存。fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; set $skip_cache 0; if ($http_cookie ~* "wordpress_logged_in_|comment_author_") { set $skip_cache 1; }
二、缓冲区大小调优:高效的数据传输
缓冲区大小直接影响Nginx处理请求的效率。 适当的缓冲区大小可以减少磁盘I/O,提升性能。
-
client_body_buffer_size: 设置客户端请求body的缓冲区大小。 如果客户端上传的文件较大,需要增加此值。client_body_buffer_size 10M; -
client_max_body_size: 设置客户端请求body的最大大小。 用于防止DDoS攻击和上传过大的文件。client_max_body_size 100M; -
proxy_buffersandproxy_buffer_size: 控制Nginx作为反向代理时,用于读取上游服务器响应的缓冲区大小。 与fastcgi_buffers和fastcgi_buffer_size类似,但用于代理场景。proxy_buffers 8 16k; proxy_buffer_size 16k; -
postpone_output: 允许Nginx在发送HTTP头之前,先缓冲一部分响应内容。 可以减少TCP连接的建立次数,提升性能。postpone_output 1460; # 通常设置为MTU大小 -
send_lowat: 设置Nginx发送数据的最小字节数。 如果发送的数据小于此值,Nginx会等待更多的数据再发送。 可以减少小数据包的发送,提升网络利用率。send_lowat 1500; # 通常设置为MTU大小
三、Gzip压缩设置:减少网络传输量
Gzip压缩可以显著减少HTTP响应的大小,从而加快页面加载速度。
-
gzip: 启用或禁用Gzip压缩。gzip on; -
gzip_types: 指定需要进行Gzip压缩的文件类型。 通常包括text/html,text/css,application/javascript,application/json,application/xml等。gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/xml application/xml+rss text/javascript; -
gzip_comp_level: 设置Gzip压缩级别。 取值范围为1-9,1表示最快的压缩速度,9表示最高的压缩比。 通常设置为4-6,以平衡压缩速度和压缩比。gzip_comp_level 6; -
gzip_min_length: 设置进行Gzip压缩的最小响应长度。 小于此值的响应不会被压缩。 可以避免压缩过小的文件,因为压缩本身会带来一定的开销。gzip_min_length 1000; -
gzip_vary: 启用Vary: Accept-Encoding头。 允许缓存服务器根据客户端是否支持Gzip压缩,缓存不同的版本。gzip_vary on; -
gzip_proxied: 指定在哪些情况下对代理的请求进行Gzip压缩。 常见的取值包括off,expired,no-cache,no-store,private,no_last_modified,no_etag,auth,any。gzip_proxied any; -
gzip_disable: 禁用Gzip压缩的客户端。 可以根据客户端的User-Agent禁用Gzip压缩。 例如,对于一些旧版本的IE浏览器,可能不支持Gzip压缩。gzip_disable "MSIE [1-6].";
四、PHP-FPM配置优化:提升PHP执行效率
PHP-FPM的配置直接影响PHP脚本的执行效率和稳定性。
-
pm: 进程管理方式。 可以选择static,dynamic, 或ondemand。static: 启动固定数量的子进程。 适用于内存充足,并且并发请求量稳定的场景。dynamic: 根据请求量动态调整子进程的数量。 适用于内存有限,或者并发请求量波动的场景。ondemand: 只有在有请求时才启动子进程。 适用于低流量的网站。
pm = dynamic -
pm.max_children: 最大子进程数量。 需要根据服务器的内存和CPU资源进行调整。 过多的子进程会导致内存溢出,过少的子进程会导致请求排队。pm.max_children = 50 -
pm.start_servers: 启动时创建的子进程数量。 适用于dynamic模式。pm.start_servers = 10 -
pm.min_spare_servers: 最小空闲子进程数量。 适用于dynamic模式。 如果空闲子进程数量小于此值,PHP-FPM会启动新的子进程。pm.min_spare_servers = 5 -
pm.max_spare_servers: 最大空闲子进程数量。 适用于dynamic模式。 如果空闲子进程数量大于此值,PHP-FPM会杀死多余的子进程。pm.max_spare_servers = 20 -
pm.max_requests: 每个子进程处理的最大请求数量。 当一个子进程处理的请求数量达到此值时,PHP-FPM会杀死该子进程,并启动一个新的子进程。 可以防止内存泄漏。pm.max_requests = 500 -
request_terminate_timeout: PHP脚本的最大执行时间。 如果PHP脚本执行时间超过此值,PHP-FPM会强制终止该脚本。 可以防止长时间运行的脚本阻塞其他请求。request_terminate_timeout = 30s -
request_slowlog_timeout: 慢日志记录的阈值。 如果PHP脚本执行时间超过此值,PHP-FPM会将该请求记录到慢日志中。 可以用于分析性能瓶颈。request_slowlog_timeout = 3s -
slowlog: 慢日志的路径。slowlog = /var/log/php-fpm/www-slow.log -
php_admin_value[memory_limit]: PHP脚本的内存限制。 需要根据应用程序的需求进行调整。php_admin_value[memory_limit] = 128M -
php_admin_value[error_log]: PHP错误日志的路径。php_admin_value[error_log] = /var/log/php-fpm/www-error.log
五、Nginx配置示例
以下是一个完整的Nginx配置示例,包含了上述所有的优化设置:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.php index.html index.htm;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # 根据你的PHP版本调整
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 60;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 16k;
# FastCGI Cache (Optional)
# fastcgi_cache_bypass $skip_cache;
# fastcgi_no_cache $skip_cache;
# set $skip_cache 0;
# if ($http_cookie ~* "wordpress_logged_in_|comment_author_") {
# set $skip_cache 1;
# }
# fastcgi_cache php_cache;
# add_header X-Cache $upstream_cache_status;
}
# Static files cache
location ~* .(jpg|jpeg|gif|png|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, max-age=31536000";
}
gzip on;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/xml application/xml+rss text/javascript;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_vary on;
gzip_proxied any;
gzip_disable "MSIE [1-6].";
}
六、PHP-FPM配置示例
以下是一个PHP-FPM配置示例(/etc/php/7.4/fpm/pool.d/www.conf):
[www]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
request_terminate_timeout = 30s
request_slowlog_timeout = 3s
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[memory_limit] = 128M
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
七、监控与调优:持续优化,保持最佳状态
性能调优是一个持续的过程。需要定期监控服务器的性能指标,并根据实际情况进行调整。
- CPU使用率: 如果CPU使用率过高,说明服务器的负载过重。 可以尝试增加子进程的数量,或者优化PHP代码。
- 内存使用率: 如果内存使用率过高,说明服务器的内存不足。 可以尝试减少子进程的数量,或者增加服务器的内存。
- 磁盘I/O: 如果磁盘I/O过高,说明服务器的磁盘性能不足。 可以尝试使用SSD硬盘,或者优化数据库查询。
- 网络流量: 如果网络流量过高,说明服务器的网络带宽不足。 可以尝试升级网络带宽,或者使用CDN加速。
- Nginx错误日志: 查看Nginx错误日志,可以发现一些潜在的问题,例如 "upstream sent too big header" 错误,或者 "504 Gateway Timeout" 错误。
- PHP-FPM慢日志: 查看PHP-FPM慢日志,可以找到执行时间较长的PHP脚本,并进行优化。
监控工具:
top: 查看CPU、内存、进程等信息。htop:top的增强版,提供更友好的界面。iostat: 查看磁盘I/O信息。vmstat: 查看虚拟内存信息。netstat: 查看网络连接信息。iftop: 实时显示网络流量。Nginx Amplify: Nginx官方提供的监控工具。PrometheusandGrafana: 流行的监控和可视化工具。
调优原则:
- 逐步调整: 每次只调整一个参数,并观察其对性能的影响。
- 基准测试: 在调整参数之前,进行基准测试,记录当前的性能指标。 在调整参数之后,再次进行基准测试,比较性能的变化。
- 模拟生产环境: 在测试环境中模拟生产环境的负载,以便更好地评估性能。
- 关注错误日志: 及时查看Nginx和PHP-FPM的错误日志,解决潜在的问题。
八、总结关键点:优化配置,提升性能
通过合理配置FastCGI参数,调整缓冲区大小,以及启用Gzip压缩,可以显著提升PHP-FPM与Nginx组合的性能,提供更快的页面加载速度和更好的用户体验。定期监控服务器性能并持续优化是保持最佳性能的关键。