好的,各位亲爱的程序员朋友们,欢迎来到今天的“Nginx与PHP-FPM的爱恨情仇”特别讲座!我是你们的老朋友,江湖人称“代码诗人”的程序猿老王。今天,咱们不谈枯燥的代码,只聊聊如何让Nginx和PHP-FPM这对黄金搭档,在你服务器上跳起优雅的华尔兹,而不是互相掐架,搞得你的网站一团糟。
开场白:一对欢喜冤家的前世今生
想象一下,你的网站就像一家餐馆,用户(顾客)点了菜(请求),Nginx就是那个帅气的服务员,负责接待客人、点单,以及把订单送到厨房。而PHP-FPM,就是那个手艺精湛的大厨,负责烹饪美食(处理PHP脚本),然后把做好的菜交给服务员(Nginx),最终送到顾客手中。
Nginx擅长静态资源的处理,它就像一个勤劳的小蜜蜂,嗖嗖嗖地就把图片、CSS、JS文件送到了用户面前。但遇到PHP这种需要“烹饪”的动态请求,它就得找PHP-FPM帮忙了。
所以,Nginx和PHP-FPM,一个负责前端接待,一个负责后端处理,分工明确,配合默契。但如果配置不当,这对搭档就会变成一对冤家,互相推诿,导致你的网站卡顿、崩溃,用户体验直线下降。😱
第一幕:Nginx的自我修养(配置篇)
首先,我们得让Nginx明白,哪些请求需要交给PHP-FPM处理。这就要用到location
指令了,它就像一个导游,告诉Nginx该怎么走。
server {
listen 80;
server_name yourdomain.com;
root /var/www/yourdomain;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # 或者 tcp:127.0.0.1:9000
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /.ht {
deny all;
}
}
这段配置的意思是:
location /
:处理所有请求,如果请求的文件或目录存在,就直接返回;否则,把请求交给index.php
处理(这就是伪静态的关键)。location ~ .php$
:处理所有以.php
结尾的请求,交给PHP-FPM处理。fastcgi_pass
:指定PHP-FPM的连接方式,可以是Unix socket(推荐)或者TCP。fastcgi_param SCRIPT_FILENAME
:告诉PHP-FPM要执行哪个PHP文件。location ~ /.ht
:禁止访问.htaccess
文件,防止敏感信息泄露。
重点解读:
try_files
指令: 这个指令非常重要,它决定了Nginx如何处理请求。它的工作原理是:依次尝试请求的文件、目录,如果都找不到,就执行最后的fallback(通常是index.php
)。fastcgi_params
文件: 这个文件包含了FastCGI协议需要的各种参数,比如SCRIPT_NAME
、REQUEST_URI
等等。Nginx会把这些参数传递给PHP-FPM,让它知道该怎么处理请求。
优化小技巧:
- 缓存静态资源: 使用
expires
指令可以缓存静态资源,减少对服务器的请求,提高访问速度。
location ~* .(jpg|jpeg|png|gif|css|js|ico)$ {
expires 30d;
log_not_found off; # 关闭404日志,减少磁盘IO
access_log off; # 关闭访问日志,减少磁盘IO
}
- Gzip压缩: 开启Gzip压缩可以减小传输的文件大小,提高访问速度。
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
第二幕:PHP-FPM的内心独白(配置篇)
PHP-FPM的配置文件通常位于/etc/php/[版本号]/fpm/pool.d/www.conf
(不同系统可能有所不同)。这里面有很多参数需要配置,但最重要的几个是:
[www]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm.sock # 或者 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.status_path = /status # 监控状态页面
request_terminate_timeout = 120s
request_slowlog_timeout = 10s
slowlog = /var/log/php7.4-fpm.log.slow
重点解读:
user
和group
: 指定PHP-FPM进程的运行用户和用户组,要和Nginx的运行用户一致(通常是www-data
)。listen
: 指定PHP-FPM监听的地址,要和Nginx的fastcgi_pass
指令对应。pm
: 指定进程管理方式,有三种:static
:启动固定数量的子进程,适用于内存充足的服务器。dynamic
:动态调整子进程数量,根据请求量自动增加或减少,适用于资源有限的服务器。ondemand
:只有在有请求时才启动子进程,适用于流量不稳定的服务器。
pm.max_children
: 指定最大子进程数量,要根据服务器的CPU和内存来调整,过大容易导致内存溢出,过小容易导致请求排队。pm.start_servers
、pm.min_spare_servers
、pm.max_spare_servers
: 这些参数控制了动态进程管理的行为,可以根据实际情况进行调整。pm.status_path
: 指定PHP-FPM状态页面的URL,可以通过这个页面监控PHP-FPM的运行状态。request_terminate_timeout
: 指定PHP脚本的最大执行时间,超过这个时间会被强制终止,防止恶意脚本占用资源。request_slowlog_timeout
和slowlog
: 指定记录慢日志的阈值和文件路径,可以用来排查性能问题。
优化小技巧:
-
调整
pm.max_children
: 这个参数是影响性能的关键因素,要根据服务器的CPU和内存来调整。一个简单的估算方法是:pm.max_children = (服务器总内存 - 其他服务占用内存) / 每个PHP进程占用内存
可以使用
top
命令或者ps
命令来查看PHP进程的内存占用情况。 -
开启OPcache: OPcache可以缓存PHP脚本的编译结果,避免重复编译,显著提高性能。
zend_extension=opcache.so opcache.enable=1 opcache.memory_consumption=128 # 建议设置为128MB以上 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.validate_timestamps=0 # 生产环境建议关闭
第三幕:性能调优的葵花宝典
配置好Nginx和PHP-FPM之后,并不意味着万事大吉。我们还需要不断地进行性能调优,才能让它们发挥出最大的潜力。
1. 监控是王道:
-
Nginx: 使用
ngx_http_stub_status_module
模块可以监控Nginx的运行状态,比如连接数、请求数等等。location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; # 允许本地访问 deny all; }
-
PHP-FPM: 通过
pm.status_path
配置的状态页面可以监控PHP-FPM的运行状态,比如活跃进程数、空闲进程数等等。 -
系统资源: 使用
top
、htop
、vmstat
等命令可以监控服务器的CPU、内存、磁盘IO等资源的使用情况。
2. 慢查询日志:
开启MySQL的慢查询日志,可以找到执行时间过长的SQL语句,然后进行优化。
3. 代码优化:
- 避免循环嵌套: 循环嵌套会大大降低代码的执行效率。
- 使用缓存: 缓存可以减少对数据库的访问,提高响应速度。
- 优化数据库查询: 使用索引、避免全表扫描、减少JOIN操作等等。
- 减少HTTP请求: 合并CSS、JS文件,使用CSS Sprites等等。
4. 使用CDN:
CDN(内容分发网络)可以将静态资源缓存到离用户更近的节点,提高访问速度。
5. 使用HTTP/2:
HTTP/2可以多路复用连接,减少延迟,提高传输效率。
表格总结:常见问题与解决方案
问题 | 可能原因 | 解决方案 |
---|---|---|
网站访问速度慢 | 1. 服务器配置不足; 2. Nginx配置不当; 3. PHP-FPM配置不当; 4. 数据库查询慢; 5. 代码效率低; 6. 静态资源未缓存 | 1. 升级服务器配置; 2. 优化Nginx和PHP-FPM配置; 3. 优化数据库查询; 4. 优化代码; 5. 开启静态资源缓存; 6. 使用CDN; 7. 开启Gzip压缩 |
网站出现502 Bad Gateway错误 | 1. PHP-FPM进程挂掉; 2. PHP脚本执行超时; 3. Nginx和PHP-FPM连接失败 | 1. 检查PHP-FPM进程是否正常运行; 2. 增加request_terminate_timeout 的值; 3. 检查Nginx和PHP-FPM的连接配置是否正确; 4. 检查服务器资源是否充足 |
网站出现504 Gateway Timeout错误 | 1. PHP脚本执行超时; 2. Nginx等待PHP-FPM响应超时 | 1. 增加request_terminate_timeout 的值; 2. 增加proxy_read_timeout 和proxy_connect_timeout 的值; 3. 优化代码,减少PHP脚本的执行时间; 4. 检查服务器资源是否充足 |
CPU占用率过高 | 1. PHP脚本执行效率低; 2. Nginx配置不当; 3. 恶意攻击 | 1. 优化PHP脚本; 2. 优化Nginx配置; 3. 部署防火墙,防止恶意攻击; 4. 增加pm.max_children 的值(但要注意内存占用); 5. 开启OPcache |
内存占用率过高 | 1. PHP-FPM进程过多; 2. 内存泄漏 | 1. 减少pm.max_children 的值; 2. 检查代码是否存在内存泄漏; 3. 重启PHP-FPM进程; 4. 升级服务器内存 |
磁盘IO过高 | 1. 频繁读写数据库; 2. 写入大量日志 | 1. 优化数据库查询; 2. 减少日志写入; 3. 使用SSD硬盘; 4. 使用缓存 |
第四幕:安全加固,防患于未然
安全是网站的生命线,我们不仅要让网站跑得快,还要让它跑得稳。
- 更新软件: 及时更新Nginx、PHP、MySQL等软件,修复已知的安全漏洞。
- 配置防火墙: 使用防火墙可以阻止恶意流量,保护服务器安全。
- 禁用不必要的模块: 禁用Nginx和PHP中不必要的模块,减少攻击面。
- 限制文件上传: 限制用户上传的文件类型和大小,防止恶意文件上传。
- 使用HTTPS: 使用HTTPS可以加密数据传输,防止数据泄露。
- 定期备份: 定期备份数据,以防万一。
尾声:代码诗人的寄语
各位朋友,今天的“Nginx与PHP-FPM的爱恨情仇”就到这里了。希望通过今天的分享,大家能够对Nginx和PHP-FPM的配置和优化有更深入的了解。记住,代码的世界,没有一劳永逸的解决方案,只有不断学习、不断探索,才能写出更优雅、更高效的代码。
最后,送给大家一句代码诗人的箴言:
“代码如诗,优雅至上,性能为王,安全护航。”
祝大家编程愉快,Bug远离!😊