各位观众老爷,大家好!我是今天的主讲人,咱们今天聊聊PHP在Nginx环境下玩转代理和FastCGI缓存,让你的网站速度嗖嗖嗖往上涨!准备好了吗?咱们这就开始!
一、Nginx代理:门卫大爷的妙用
想象一下,Nginx就像你家小区门口的门卫大爷,它负责接收所有进来的请求,然后决定把这些请求分发给谁处理。这就是所谓的“反向代理”。
1. 为什么要用代理?
- 负载均衡: 如果你家有多个PHP服务器(想象成多个辛勤工作的程序员),Nginx可以把请求均匀地分配给他们,避免某个程序员累死,其他人闲死。
- 安全: 隐藏你的真实服务器IP地址,让坏人没法直接攻击你的PHP服务器。
- 缓存: Nginx可以缓存一些静态资源(图片、CSS、JS),减轻PHP服务器的压力。
- 动静分离: 让Nginx处理静态资源,PHP处理动态请求,各司其职,效率更高。
2. 如何配置Nginx代理?
咱们先来看一个简单的Nginx配置:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://php_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
upstream php_upstream {
server 192.168.1.101:9000;
server 192.168.1.102:9000;
}
listen 80;
: 监听80端口,也就是HTTP请求的默认端口。server_name example.com;
: 你的域名。location / { ... }
: 匹配所有请求。proxy_pass http://php_upstream;
: 把请求转发到名为php_upstream
的upstream块。proxy_set_header ...
: 设置一些HTTP头信息,让PHP服务器知道客户端的真实IP地址等信息。这个非常重要,不然你的PHP程序可能拿不到正确的客户端IP。upstream php_upstream { ... }
: 定义一个upstream块,包含多个PHP服务器的地址和端口。
解释一下这些proxy_set_header
的含义:
Header | 作用 |
---|---|
Host |
传递原始的Host请求头,让PHP知道用户访问的是哪个域名。 |
X-Real-IP |
传递客户端的真实IP地址。 Nginx收到请求时知道客户端IP,但是转发给PHP之后,PHP看到的IP就是Nginx的IP了。这个头就是用来把客户端真实IP传递给PHP的。 |
X-Forwarded-For |
如果客户端经过了多个代理服务器,这个头会包含所有代理服务器的IP地址,用逗号分隔。$proxy_add_x_forwarded_for 会把当前的客户端IP添加到已有的X-Forwarded-For 头中。 |
X-Forwarded-Proto |
传递客户端使用的协议(HTTP或HTTPS)。如果你的Nginx配置了SSL,并且希望PHP知道用户是通过HTTPS访问的,这个头就很有用。 |
二、FastCGI缓存:给PHP穿上防弹衣
FastCGI缓存就像一个盾牌,它可以把PHP生成的页面缓存起来,下次用户访问相同的页面时,直接从缓存中读取,而不需要再次执行PHP代码。这样可以大大减轻PHP服务器的压力,提高网站的响应速度。
1. 为什么要用FastCGI缓存?
- 性能提升: 显著提高网站的响应速度,尤其是在访问量大的时候。
- 减轻服务器压力: 减少PHP的执行次数,降低CPU和内存的使用率。
- 提高用户体验: 更快的页面加载速度,让用户感觉更流畅。
2. 如何配置FastCGI缓存?
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=php_cache:100m inactive=60m max_size=1g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # 你的PHP-FPM socket路径
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_cache php_cache;
fastcgi_cache_valid 200 301 302 60m; # 缓存HTTP状态码为200, 301, 302 的页面60分钟
fastcgi_cache_valid any 10m; # 缓存所有其他状态码的页面10分钟 (可以根据需要调整)
fastcgi_cache_min_uses 1; # 页面至少被访问一次才会被缓存
fastcgi_cache_bypass $skip_cache; # 如果$skip_cache为真,则绕过缓存
fastcgi_no_cache $skip_cache; # 如果$skip_cache为真,则不使用缓存
}
# 禁止访问 .ht 文件
location ~ /.ht {
deny all;
}
}
咱们来逐行解释一下这些配置:
-
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=php_cache:100m inactive=60m max_size=1g;
: 定义FastCGI缓存的路径、层级、缓存区名称、过期时间、最大容量。/var/cache/nginx
: 缓存文件存放的目录。levels=1:2
: 设置目录层级,可以提高缓存文件的查找速度。keys_zone=php_cache:100m
: 定义一个名为php_cache
的缓存区,大小为100MB。这个缓存区用来存储缓存键和元数据。inactive=60m
: 如果一个缓存文件在60分钟内没有被访问,就会被删除。max_size=1g
: 缓存目录的最大容量为1GB。
fastcgi_cache_key "$scheme$request_method$host$request_uri";
: 定义缓存键的生成规则。这里使用了协议、请求方法、主机名和URI作为缓存键。这意味着只有完全相同的请求才会被认为是相同的页面,从而命中缓存。fastcgi_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504;
: 在服务器出错、超时或者返回错误状态码时,可以使用过期的缓存。这可以提高网站的可用性,即使后端服务器出现问题,用户仍然可以访问到缓存的页面。fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
: 忽略来自PHP的Cache-Control
、Expires
和Set-Cookie
头信息。因为Nginx自己会管理缓存,所以不需要PHP来控制。fastcgi_cache php_cache;
: 启用名为php_cache
的缓存区。fastcgi_cache_valid 200 301 302 60m;
: 缓存HTTP状态码为200、301、302的页面60分钟。fastcgi_cache_valid any 10m;
: 缓存所有其他状态码的页面10分钟。fastcgi_cache_min_uses 1;
: 页面至少被访问一次才会被缓存。fastcgi_cache_bypass $skip_cache;
: 如果$skip_cache
变量为真,则绕过缓存。fastcgi_no_cache $skip_cache;
: 如果$skip_cache
变量为真,则不使用缓存。
3. 如何控制缓存?
有时候,你可能需要控制哪些页面应该被缓存,哪些页面不应该被缓存。比如,用户登录后的页面就不应该被缓存。你可以通过设置$skip_cache
变量来实现:
<?php
// 在你的PHP代码中
if (isset($_SESSION['user_id'])) {
header('X-Accel-Expires: 0'); // 禁用缓存
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
}
?>
然后在Nginx配置中:
map $request_uri $skip_cache {
default 0;
~*"/wp-admin/|/xmlrpc.php|/wp-.*.php|/feed/|index.php|sitemap(_index)?.xml" 1; # WordPress常见的不缓存的URL
~*"/private/" 1; # 以/private/开头的URL不缓存
~*"?nocache=1" 1; # URL中包含?nocache=1时不缓存
if ($http_cookie ~* "wordpress_logged_in_|wp-postpass_") {
set $skip_cache 1; # 如果用户已登录,则不缓存
}
}
map $request_uri $skip_cache { ... }
: 定义一个map块,根据$request_uri
变量的值来设置$skip_cache
变量的值。default 0;
: 默认情况下,$skip_cache
的值为0,表示启用缓存。~*"/wp-admin/|/xmlrpc.php|/wp-.*.php|/feed/|index.php|sitemap(_index)?.xml" 1;
: 如果请求的URI匹配这些正则表达式,则$skip_cache
的值为1,表示不缓存。 这里针对WordPress常见的URL进行了排除。~*"/private/" 1;
: 如果URL包含/private/
,则跳过缓存。可以自定义任何你想要排除的URL。~*"?nocache=1" 1;
: 如果URL中包含?nocache=1
,则跳过缓存。if ($http_cookie ~* "wordpress_logged_in_|wp-postpass_") { set $skip_cache 1; }
: 如果用户已登录(通过Cookie判断),则跳过缓存。
三、优化技巧:让缓存飞起来
- 合理设置缓存时间: 缓存时间太短,缓存效果不明显;缓存时间太长,可能会导致用户看到过时的内容。根据你的网站内容更新频率,合理设置缓存时间。
- 区分静态资源和动态页面: 静态资源(图片、CSS、JS)可以缓存更长时间,动态页面应该缓存较短时间或者不缓存。
- 使用CDN: CDN(内容分发网络)可以把你的网站内容缓存到全球各地的服务器上,让用户从离他们最近的服务器上访问,提高访问速度。
- 监控缓存命中率: 通过Nginx的日志或者监控工具,可以查看缓存命中率。如果缓存命中率太低,说明缓存配置可能需要调整。
- 清理缓存: 有时候,你需要手动清理缓存,比如在网站更新或者修改了配置之后。你可以通过删除缓存目录中的文件来清理缓存。
四、常见问题:手把手教你排雷
- 缓存未生效: 检查Nginx配置是否正确,缓存目录是否存在,权限是否正确,PHP代码是否设置了禁用缓存的头信息。
- 用户看到过时的内容: 缩短缓存时间,或者手动清理缓存。
- 缓存命中率低: 检查缓存键的生成规则是否合理,是否有很多不同的URL访问相同的页面。
- 服务器CPU占用率高: 检查是否缓存了大量的动态页面,或者缓存时间太短,导致缓存频繁更新。
五、总结:让你的网站速度起飞!
通过合理配置Nginx代理和FastCGI缓存,可以让你的PHP网站速度得到显著提升,减轻服务器压力,提高用户体验。记住,没有一劳永逸的配置,需要根据你的网站情况不断调整和优化。
希望今天的讲座对你有所帮助!如果有什么问题,欢迎提问。 祝大家编程愉快,网站速度飞起!