利用nginx反向代理緩存減小PHP的壓力

問題:對於某些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返回的內容;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章