问题:对于某些PHP的接口,请求很频繁,但是这些接口返回的数据又不是实时的,即存在一定的延时性。
分析:可以将这些接口返回的数据缓存起来,减少PHP执行的频率。
一般有2种方法缓存这些数据:
1、在PHP端缓存,如:yac,memcache,redis等。
2、在NGINX端缓存,如利用proxy_cache。
这里讨论在NGINX端缓存,利用NGINX的反向代理缓存可以达到这个效果。
NGINX反向代理缓存是将请求参数作为key,PHP返回的数据作为value,缓存到磁盘中。
比如客户端请求:https://baixiume.com/user/info,NGINX将该请求作为key,通过某种算法得到类似hash的key值,
PHP返回:http-header和http-body,NGINX将该输出的数据作为value,
然后缓存到指定的磁盘目录中,下次客户端再请求时,NGINX会查找是否存在该key,存在则直接读取value返回,
否则再将请求代理给PHP。
配置步骤:
1、在HTTP段配置缓存的目录
proxy_cache_path /var/log/nginx/proxy_cache levels=1:2 keys_zone=one:100m inactive=30m max_size=100m use_temp_path=off;
参数解析:
1、/var/log/nginx/proxy_cache,nginx会将数据缓存到这个目录下,/var/log/nginx目录需要手动创建,NGINX会自动创建proxy_cache目录;
2、levels=1:2,设置缓存文件目录层次,这里使用2级目录,即第一级是目录,第二级才是缓存的数据文件;
3、keys_zone=one:100m,定义一块名称叫做one的区域,来保存key值,大小为100m,这样当请求到来时,NGINX可以快速找到是否存在相应的key;
4、inactive=30m,缓存的过期检查周期,30分钟后没人访问的,就删除one下的缓存;
5、max_size=100m,缓存的数据文件大小,当one下的缓存超过100m时,会删除前面的缓存;
6、use_temp_path=off,nginx 会将缓存文件直接写入指定的 cache 文件中,而不使用 proxy_temp_path 指定的临时存储路径;
2、在server段配置指定的缓存接口
location ~ .+(user\/info)$ {
proxy_cache_methods POST;
proxy_cache one;
proxy_cache_valid 200 10m;
proxy_cache_key "$request_uri|$request_body";
proxy_ignore_headers "Expires";
proxy_ignore_headers "Cache-Control";
add_header X-Cached $upstream_cache_status;
proxy_pass http://127.0.0.1:4431;
proxy_redirect http://127.0.0.1:4431/ /;
#proxy_redirect off;
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-For-Proxy $http_y_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
1、proxy_cache one,使用在http段中定义的one区块;
2、proxy_cache_valid 200 10m,PHP返回状态为200的请求才缓存,并且10分钟后过期;
3、proxy_cache_key "$request_uri|$request_body",用$request_uri|$request_body作为key值,尽量让$request_uri唯一,这样就不用$request_body了,提高速度;
4、proxy_ignore_headers "Expires";
proxy_ignore_headers "Cache-Control"; 忽略这2个头部字段,根据实际情况可能还要忽略其他字段,否则NGINX可能不会缓存某些已过期的接口;
5、add_header X-Cached $upstream_cache_status,给客户端返回缓存的命中情况,浏览器F12可以看到X-Cached字段,有Hit命中,Expired过期,Miss不存在等值;
3、配置代理的端口服务
server {
listen 127.0.0.1:4431;
listen [::1]:4431 ipv6only=on;
keepalive_timeout 0;
server_name localhost ;
access_log logs/access_4431.log access;
location ~ .+\.php($|/) {
allow 127.0.0.1;
#deny all;
root /var/web;
set $script $uri;
set $path_info "/";
if ($uri ~ "^(.+\.php)(/.+)") {
set $script $1;
set $path_info $2;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_read_timeout 10m;
fastcgi_index index.php?IF_REWRITE=1;
include fastcgi_params;
fastcgi_param PATH_INFO $path_info;
fastcgi_param SCRIPT_FILENAME $document_root$script;
fastcgi_param SCRIPT_NAME $script;
}
}
就是正常的代理给PHP的server段的配置;
4、重启NGINX,然后访问上面设置的缓存接口,在/var/log/nginx/proxy_cache目录下看到缓存的数据文件,
在该目录下grep一下能搜到PHP返回的内容;