基于nginx实现缓存功能及uptream模块详细使用方法
基于nginx實現緩存功能及uptream模塊詳細使用方法
一般情況下,前端使用nginx做代理或7層負載并向后實現varish/squid做cache?server的效果要好的多
?
nginx與squid做緩存比較
nginx比squid有著巨大的優勢表現在:
nginx是異步
假如后端的web服務器,當用戶的請求到達nginx的時候,nginx收到請求而不是立即將請求轉發至web?server;
如果用戶請求比較大,nginx將其在本地緩存,內存中不夠用則在磁盤中緩存,當緩存完畢之后,再將請求一次性提交至后端web服務器,轉發完成之后再向客戶端響應
也就意味著用戶的連接只需要跟nginx建立連接即可,nginx與后端web一般都在內網中對接,只要帶寬滿足,很可能瞬間完成,因此來說對于后端服務器的壓力及小,只需要建立幾秒的連接就可以處理完成非常大的請求
squid是同步
當用戶請求到達squid中,在剛接收到用戶請求的第一個報文立即與后端建立連接,因此在處理過程中,依舊保持著連接
所以說,nginx最大的優勢就是在用戶的連接處理的場景中
這樣就使前端有大量的用戶請求連接,但是在后端看上去只有少數部分
比如前端有1W并發進來,后端大概只能看到其10分之1?,需要查找數據庫的只有少數部分,所以后端的web壓力會小,但是前端分發器的壓力會很大
nginx緩存機制
nginx要想實現反向代理那么就需要使用proxy_cache模塊,以及配合其指令和參數,可以將用戶的請求從上游服務器獲取之后先存在本地磁盤
緩存通常是鍵值對方式存儲
鍵?:?請求的rul
值?:?后端服務器響應的內容
?
所以當后續用戶的請求到達之后,如果本地緩存服務器中存在的話則直接封裝報文返回至用戶
但是如果服務器運行了很久,已保存N久的緩存數據,那在某一時刻后端服務器出現故障,nginx緩存已經無法找到其后端的服務器,那么緩存上游服務器對象是否還應該返回至用戶
這些都是可配置的,我們定義緩存的時候,像這些緩存是否可緩存,緩存的位置都要自己去配置的,并且一旦服務器故障,緩存的數據還能否直接響應客戶端等等
?
事實上用戶所在瀏覽器上保存的緩存稱為私有緩存,而服務器上緩存的數據叫做公共緩存
?
有些數據只能在私有緩存中進行緩存,比如:
用戶登錄網站的用戶名和密碼的信息,這類肯定不能在服務器上緩存;
而用戶的cookie信息一般也不能緩存,所以緩存服務器公共緩存服務器只要發現用戶請求中有cookie則不緩存,但是一般電商站點為了追中用戶的行為規則,則將每個請求數都加cookie,但對于圖片這種靜態內容附加cookie是沒有意義的
所以對于緩存服務器來說必須處理這種機制,對于沒必要加cookie的而用戶已加cookie將其刪掉并讓緩存命中等,因此需要一系列緩存機制,這都是需要自己去定義的,比如緩存多久否定緩存多久?重定向緩存多久?...
?
配置Nginx緩存
參考:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_path
語法
proxy_cache_path?path?[levels=levels]?keys_zone=name:size?[inactive=time][max_size=size]?[loader_files=number]?[loader_sleep=time][loader_threshold=time];
(需要注意的是標紅的字體)
配置格式:
proxy_cache_path/data/nginx/cache?levels=1:2?keys_zone=one:10m;
#定義/data/nginx/cache為緩存目錄;
levels=1:2有2級子目錄,最多為3級子目錄,用冒號隔開定義3個數字,每個數字表示其目錄名稱;
keys_zone=one:10m用多大的空間保存鍵值;
以下為緩存對象的名字,方便引用并且避免名稱沖突
file?names?in?acache?will?look?like?this:
/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
?
使用示例
定義緩存必須在全局配置上下文中去定義
http?{
???proxy_cache_path??/data/nginx/cache??levels=1:2???keys_zone=STATIC:10m
proxy_cache_path?/data/nginx/cache?levels=1:2??keys_zone=STATIC:10m
inactive=24h??max_size=1g;
}
proxy_cache_path必須定義在全局配置中,定義完之后可以在各location中來引用
在location中來使用proxy_cache來指定是否使用緩存,也可以定義多個緩存在location中引用不同的緩存定義
server?{
????????location?/?{
???????????proxy_pass?????????http://www.test.com;
???????????proxy_set_header???????Host?$host;
???????????proxy_cache????????STATIC;
???????????proxy_cache_valid??????200??1d;#請求返回值為200的則緩存1day
???????proxy_cache_valid??????301302?10m;#請求返回值為301?302的則緩存10m
???????????proxy_cache_vaild??????any1m;#其他任何返回值緩存1m
?
#是否可以使用過期對象
???????????proxy_cache_use_stale??error?timeout?invalid_header?updating
???????http_500?http_502?http_503?http_504;
????????}
????}
}
實現緩存機制
步驟:
(1)定義緩存必須在http全局中定義
(2)而后在location中實現反向代理才有必要實現緩存
創建緩存目錄
[root@node1?~]#mkdir?-p?/data/cache/nginx/
編輯nginx配置文件
[root@node1?nginx]#?vim?nginx.conf
在http?{?}上下文中定義緩存
proxy_cache_path/data/cache/nginx/??levels=1:2?keys_zone=one:10mmax_size=1g;
定義/data/cache/nginx/為緩存目錄;
levels=1:2?有2級子目錄,最多為3級子目錄,用冒號隔開定義3個數字,每個數字表示其目錄名稱;
keys_zone=one:10m?用多大的空間保存鍵值,最大為10M;
max_size=1g?表示緩存空間最大有1G;
在location中定義緩存規則并調用proy_cache_path
location?/?{
proxy_pass?http://10.0.10.83;#將請求都轉發至10.0.10.83上去
proxy_cache?one;#明確說明使用名稱one這個cache
?
#以下為緩存規則
proxy_cache_valid?200?1h;
proxy_cache_valid?302?10m;
proxy_cache_valid?any?1m;
}
保存退出檢查語法并重新加載
[root@node1?nginx]#nginx?-t
nginx:?theconfiguration?file?/etc/nginx/nginx.conf?syntax?is?ok
nginx:configuration?file?/etc/nginx/nginx.conf?test?is?successful
[root@node1?nginx]#nginx?-s?reload
查看緩存目錄
[root@node1?nginx]#ll?-th?/data/cache/nginx/
total?0
看到目錄中是空的,那么我們來使用curl命令訪問一下看其是否能生成緩存文件
[root@node1?nginx]#curl?10.0.10.61
<h1>10.0.10.83</h1>
再次查看路徑
[root@node1?nginx]#ll?-th?/data/cache/nginx/f/63/
total?4.0K
-rw-------.?1?nginxnginx?350?May9?16:06681ad4c77694b65d61c9985553a2763f
這時候目錄中已經存在緩存信息,說明緩存已經生效,但是在某些場合,我們不能保證其已經被命中
那么再將upstream模塊開啟,因為upstream模塊會給我們引入一些新的服務器變量,編輯如下:
upstream?webservers{#定義名稱
server?10.0.10.83;
#server?10.0.10.61;#將之前定義的注釋
}
再定義location
???????location?/?{
????????????proxy_pass?http://webservers;#引用upstream名稱
????????????proxy_cacheone;#引用定義的緩存模塊名稱
???????????proxy_cache_valid?200?1h;
???????????proxy_cache_valid?302?10m;
???????????proxy_cache_valid?any?1m;
????????}
這樣表示我們已經啟用了upstream模塊了而upstream模塊會給我們引入一些新的服務器變量進來
比如cache_status,如果我們訪問某個緩存頁面的時候到底是否命中會通過這個變量保存下來,如果將其傳遞給客戶端,那么我們就知道是否命中了
再將其加入首部header
location?/?{
#root/web/htdocs/;
#indexindex.php?index.html?index.htm;
proxy_pass?http://webservers;
proxy_cache?one;
proxy_cache_valid?200?1h;
proxy_cache_valid?302?10m;
proxy_cache_valid?any?1m;
add_header?X-Via?$server_addr;#定義這個header名為X-Via?通過變量$server_addr明確說明從哪個服務器來響應的?server_addr
add_header?X-Cache-Status$upstream_cache_status;#明確說明是否命中$upstream_cache_status為upstream模塊
}
保存退出并檢測語法
[root@node1?nginx]#/usr/local/nginx/sbin/nginx?–t
[root@node1?nginx]#/usr/local/nginx/sbin/nginx?–s?reload
重新reload之后刷新測試,這里使用的是Google?Chrome瀏覽器
如上所示,提示已命中,X-Via是我們自定義的header標簽
也可以使用curl?-I來查
[root@node1?nginx]#curl?-I?http://10.0.10.61
HTTP/1.1?200?OK
Server:?nginx/1.4.2
Date:?Fri,?09?May2014?08:22:41?GMT
Content-Type:text/html
Content-Length:?20
Connection:keep-alive
Last-Modified:?Mon,12?Aug?2013?10:48:13?GMT
ETag:?"fd91-14-4e3bddc687540"
X-Via:10.0.10.61
X-Cache-Status:HIT
Accept-Ranges:bytes
啟動壓縮功能
nginx將響應報文發送至客戶端之前可以啟用壓縮功能,這能夠有效地節約帶寬,并提高響應至客戶端的速度。通常編譯nginx默認會附帶gzip壓縮的功能,因此,可以直接啟用之。
http?{
gzip?on;
?????gzip_http_version?1.0;
?????gzip_comp_level?2;
?????gzip_types?text/plain?text/cssapplication/x-javascript?text/xml?application/xml?application/xml+rsstext/javascript?application/javascript?application/json;
?????gzip_disable?msie6;?????#如果對方是ie6的話,則不再使用壓縮功能,,因為ie6瀏覽器不支持壓縮
}
gzip_proxied指令可以定義對客戶端請求哪類對象啟用壓縮功能,如“expired”表示對由于使用了expire首部定義而無法緩存的對象啟用壓縮功能,其它可接受的值還有“no-cache”、“no-store”、“private”、“no_last_modified”、“no_etag”和“auth”等,而“off”則表示關閉壓縮功能
重新加載配置文件并訪問
?
upstream模塊的使用
upstream模塊常用的指令有:
·ip_hash:?基于客戶端IP地址完成請求的分發,它可以保證來自于同一個客戶端的請求始終被轉發至同一個上游服務器,與lvs的機制是一樣的;
·keepalive:每個worker進程為發送到upstream服務器的連接所緩存的個數;轉發至服務器之后能否使用長連接,也盡可能避免三次握手與四次斷開的次數,如果參數過大的話,會無形之中對后端服務器產生很大的壓力,因此建議開啟但不要太大
·least_conn:最少連接調度算法;類似于lvs的wlc算法的效果,因此一般來盡量避免和ip_hash一起用
server:定義一個upstream服務器的地址,還可包括一系列可選參數,如:
·weight:權重;
·max_fails:最大失敗連接次數,失敗連接的超時時長由fail_timeout指定;
·fail_timeout:等待請求的目標服務器發送響應的時長;
·backup:用于fallback的目的,所有服務均故障時才啟動此服務器;
·down:手動標記其不再處理任何請求;
示例:
????upstream?backend?{
???????server?www.magedu.com?weight=5;
???????serverwww2.magedu.com:8080???????max_fails=3?fail_timeout=30s;
?????}
upstream模塊也能為非http類的應用實現負載均衡,如下面的示例定義了nginx為memcached服務實現負載均衡
?upstreammemcachesrvs?{??????????#明確定義了一組實現負載均衡的服務器
??????????server172.16.100.6:11211;??#而這組服務器向后分發的端口都是11211?,是memcache的服務器端口
??????????server172.16.100.7:11211;
?????}
????server?{
??????????location?/?{
??????????set?$memcached_key"$uri?$args";?????#向后端memcache查詢的時候,查詢鍵是$uri?和$args組合起來的值
??????????memcached_passmemcachesrvs;?????#通過memcachepass傳遞至memcachesrvs組服務器
??????????error_page?404?=?@fallback;????#如果沒有命中則則發送至其上游的其他服務器
??????????}
location?@fallback?{????????????
?????????????????proxy_passhttp://127.0.0.1:8080;
??????????}
????}
這樣一來,找緩存的時候先在memcached里查找,如果不存在則再去找真實服務器,這樣將nginx將memcached結合在了一起,將數據直接緩存在memcached內存當中,而不是nginx自己的緩存當中
?
實現后端服務器健康狀態檢查
使其一旦出現故障不再將其加進來
定義upstream:
???upstream?webservers?{
server?10.0.10.83?weight=1?max_fails=3fail_timeout=2s;?#最大允許3次失敗,如果超過2秒則算超時
server?10.0.10.61?max_fails=3fail_timeout=1s?backup;#backup表示其主機始終不會生效除非組內所有主機全部故障
????}
一般如果條件允許的情況下,本機也啟動一個web服務器,但是這個服務器不是專門提供工作的,一旦后端服務器出現故障,那么則轉至backup服務器,使其服務器專門為用戶提供錯誤頁面
proxy_cache通常也只能緩存本地服務器向后端服務器取得數據而進行緩存的,而后端通常都是靜態服務器,如果基于fastcgi的方式獲取數據的,而有希望對動態內容作緩存,那么就要涉及到fastcgi的自身緩存功能了
實現動態內容緩存
通過FastCGI協議取得的內容頁可以緩存,但是時長需要自定義好
使用時將fastcgi_cache模塊啟用并定義參數即可,之前我們搭建了一套lnmp?這時我們要對fastcgi進行緩存
定義緩存目錄
[root@node1?nginx]#mkdir?-p?/data/cache/fastcgi
編輯配置文件,在http{}中加入以下參數:
fastcgi_cache_path/data/cache/fastcgi?levels=1:2:1?keys_zone=fcgi:20m?max_size=1g;
定義/data/cache/fastcgi為fastcgi緩存目錄;
緩存目錄分別為3級子目錄;
Fcgi緩存大小為20M;
最大緩存為1G的空間;
而后location中啟用fastcgi
???????location?~?\.php$?{
???????????root??????/web/htdocs/;
???????????fastcgi_pass??127.0.0.1:9000;
???????????fastcgi_index??index.php;
???????????fastcgi_param??SCRIPT_FILENAME??/scripts$fastcgi_script_name;
???????????include????????fastcgi_params;
???????}
以上參數為nginx默認配置,將以上參數啟用之后,我們還需要對其加入一些參數:
???????location?~?\.php$?{
???????????root???????????/web/htdocs/;
???????????fastcgi_pass???127.0.0.1:9000;
???????????fastcgi_index??index.php;
???????????fastcgi_param??SCRIPT_FILENAME??/scripts$fastcgi_script_name;
???????????include????????fastcgi_params;
???????????fastcgi_cache?fcgi;
???????????fastcgi_cache_valid?200?10m?;
???????????fastcgi_cache_valid?301?2m?;
???????????fastcgi_cache_valid?any?1m?;
????????}
保存退出并檢查語法
[root@node1?nginx]#nginx?-t
nginx:?theconfiguration?file?/etc/nginx/nginx.conf?syntax?is?ok
nginx:configuration?file?/etc/nginx/nginx.conf?test?is?successful
重新加載配置文件
[root@node1?nginx]#nginx?-s?reload
這時我們再去請求動態內容
[root@mode?~]#?curlhttp://10.0.10.61/index.php
再來查看是否生產緩存
[root@node1?~]#?ll/data/cache/fastcgi/e/27/4/
total?48
-rw-------.?1?nginxnginx?45873?May?10?12:55?d41d8cd98f00b204e9800998ecf8427e
?
使用ab壓力測試其效果是否明顯
首先將fastcgi緩存功能關閉
location?~?\.php$?{
root/web/htdocs;
fastcgi_pass?127.0.0.1:9000;
fastcgi_indexindex.php;
fastcgi_paramSCRIPT_FILENAME/scripts$fastcgi_script_name;
includefastcgi_params;
#將以下參數注釋
#fastcgi_cache?fcgi;
#fastcgi_cache_valid?200?10m?;
#fastcgi_cache_valid?301?2m?;
#fastcgi_cache_valid?any?1m?;
}
重新加載配置文件
[root@node1?nginx]#nginx?-s?reload
使用ab命令對其進行壓力測試
[root@mode?~]#?ab-c?100?-n?2000?http://10.0.10.61/index.php
我們只關心Requests值?所以略過一部分信息
#···········略··············
Document?Path:/index.php
DocumentLength:45234?bytes
?
ConcurrencyLevel:100
Time?taken?fortests:4.343977?seconds
Completerequests:2000
Failedrequests:228
(Connect:?0,?Length:?228,?Exceptions:?0)
Write?errors:0
Totaltransferred:90761752?bytes
HTML?transferred:90467752?bytes
Requests?per?second:460.41?[#/sec]?(mean)
Time?perrequest:217.199?[ms]?(mean)
Time?perrequest:2.172?[ms]?(mean,?acrossall?concurrent?requests)
Transfer?rate:20403.88?[Kbytes/sec]?received
#···········略··············
將緩存模塊開啟再次對其進行壓力測試
得出數據:
ConcurrencyLevel:100
Time?taken?fortests:1.576516?seconds
Completerequests:2000
Failedrequests:0
Write?errors:0
Totaltransferred:90896000?bytes
HTMLtransferred:90602000?bytes
Requests?per?second:1268.62?[#/sec]?(mean)
Time?perrequest:78.826?[ms]?(mean)
Time?perrequest:0.788?[ms]?(mean,?acrossall?concurrent?requests)
Transfer?rate:56304.53?[Kbytes/sec]?received
?
?至此,試驗結束,感謝各位
?
?
?
?
轉載于:https://blog.51cto.com/yijiu/1409177
總結
以上是生活随笔為你收集整理的基于nginx实现缓存功能及uptream模块详细使用方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 免费社交类图标集
- 下一篇: Zabbix中文模式:图片下面的字符乱码