Web Cachephp
程序運行具備局部性:css
時間局部性html
空間局部性web
key-value:算法
key: 訪問路徑,URL, hashapache
value:web content編程
數據具備熱點:後端
緩存命中率:hit/(hit+miss)centos
文檔命中率:從文檔個數進行衡量;緩存
字節命中率:從內容大小進行衡量;
緩存的生命週期:
緩存清理:緩存項過時、緩存空間耗盡;
緩存與否:
私有數據:不可緩存;
緩存處理的步驟:
接收請求 --> 解析請求 (提取請求的URL及各類首部)--> 查詢緩存 --> 新鮮度檢測 --> 建立響應報文 --> 發送響應 --> 記錄日誌
緩存控制機制:
一、過時日期:
HTTP/1.0 Expires
示例:Expires:Thu, 04 Jun 2015 23:38:18 GMT 指明絕對時間,可是受時區的影響;
HTTP/1.1 Cache-Control: max-age
示例:Cache-Control:max-age=3600 指明3600秒過時,相對時長;
Cache-Control = "Cache-Control" ":" 1#cache-directive
cache-directive = cache-request-directive
| cache-response-directive
cache-request-directive = 請求
"no-cache"
| "no-store" (backup)
| "max-age" "=" delta-seconds
| "max-stale" [ "=" delta-seconds ]
| "min-fresh" "=" delta-seconds
| "no-transform"
| "only-if-cached"
| cache-extension
cache-response-directive = 響應
"public" 能夠放在共同緩存之上
| "private" [ "=" <"> 1#field-name <"> ] 只能私有緩存
| "no-cache" [ "=" <"> 1#field-name <"> ] 可緩存,必須在響應客戶端前,驗證緩存有效與否
| "no-store" 不可緩存
| "no-transform"
| "must-revalidate" 必須作從新校驗
| "proxy-revalidate"
| "max-age" "=" delta-seconds
| "s-maxage" "=" delta-seconds 共同緩存時長
| cache-extension
二、有效性再驗正:revalidate
若是原始內容未改變,則僅響應首部(不附帶body部分),響應碼304 (Not Modified)
若是原始內容發生改變,則正常響應,響應碼200;
若是原始內容消失,則響應404,此時緩存中的緩存項也應該被刪除;
條件式請求首部:
If-Modified-Since:基於原始內容的最近一個修改時間戳進行;自從某某時間,發生改變,則返回新的內容,響應碼爲200;沒發生改變,則返回響應碼304;
If-Unmodified-Since:
If-Match:
If-None-Match:基於Etag(擴展標記)的比較進行;若是不匹配,則返回新的內容,響應碼爲200,不然返回響應碼304
示例:Etag: faiy89345
Web Cache:常見的緩存服務開源解決方案:squid, varnish
varnish官網:https://www.varnish-cache.org
varnish經過能夠基於文件系統接口進行訪問的共享內存區域來記錄日誌(shared memory log);默認爲90M;分爲兩部分:
前半部分是計數器
後半部分爲客戶端請求的數據
vcl:Varnish Configuration Language:varinish配置語言
緩存策略配置接口;
基於「域」的簡單編程語言;
varnish緩存內容的存儲:
(1)file:自管理的文件系統,黑盒,不支持持久機制;
(2)malloc:使用malloc()庫調用在varnish啓動時向內存申請指定大小的空間,不支持持久機制;
(3)persistent:與file功能相同,基於文件的持久存儲,仍處於測試期;
指明緩存存儲:-s [name=]type[,options]
malloc[,size]
file[,path[,size[,granularity]]]
persistent,path,size
varnishd v4程序的選項有兩類:
程序選項:
-s,-f,...
運行時選項:
-p param=value
配置進程特性:centos7:/etc/varnish/varnish.params
配置緩存策略:centos7:/etc/varnish/default.vcl
服務:systemctl start varnish.service
vcl:「域」專用的編程語言;狀態引擎:state engine;
VCL存在多個狀態引擎,狀態之間存在相關性,但彼此間相互隔離;每一個引擎使用return(x)來退出當前狀態,並轉入下一狀態;不一樣狀態的引擎,其x是不盡相同;
請求處理流程:
(1)請求的爲可緩存:
(a)命中:經過本地緩存響應;
(b)未命中:到後端服務器取得響應內容;
可緩存對象:先緩存再響應;定義緩存時間、自定義緩存鍵;
不可緩存對象:不緩存而直接響應;
(2)請求的爲不可緩存:到後端服務器取得直接響應;
varnish finate state machine:
vcl_rec:
hit:vcl_hit:
miss:vcl_miss
purge:vcl_purge
pipe:vcl_pipe
pass,hit_for_pass:vcl_pass
vcl_hash:lookup
vcl_backend_fetch
vcl_backend_response
vcl_backend_error
vcl_synth
vcl_deliver:
數據報文處理流向:
vcl_recv---》vcl_hash---》
(1)vcl_hit---》
(a)vcl_deliver
(b)vcl_pass---》vcl_backend_fetch
(2)vcl_miss---》
(a)vcl_pass
(b)vcl_backend_fetch
(3)vcl_purge---》vcl_synth
(4)vcl_pipe---》
vcl_backend_fetch---》
vcl_backend_response---》vcl_deliver
vcl_backend_error
vcl的語法:
(1)//,#,/*...*/,:註釋
(2)sub $name:定義子例程;
(3)不支持循環,支持條件判斷;
(4)有內建變量;
(5)使用終止語句return,沒有返回值;
(6)操做符:=,==,!=,~,&&,||
測試使用示例1:判斷是否命中與對應的server ip;
sub vcl_deliver{
if (obj.hits>0) {
set resp.http.X-Cache = "HIT" + " " + server.ip;
} else {
set resp.http.X-Cache = "MISSS" + " " + server.ip;
}
}
測試使用示例2:禁止test.html使用緩存;
sub vcl_recv{
if (req.url ~ "^/test.html$") {
return(pass);
}
}
測試使用示例3:強制對某資源的請求不檢查緩存:
sub vcl_recv{
if (req.url ~ "(?i)~/login" || req.url ~ "(?i)^/admin" { // (?i)此處表示不區分大小寫
return(pass);
}
}
對特定類型的資源,例如公開的圖片等,取消其私有標識,並強行設定其能夠由varnish緩存的時長;
sub vcl_backend_response{
if (bereq.url ~ "(?i)\.jpg$") {
set beresp.ttl = 7200s;
unset beresp.http.Set-Cookie;
}
if (bereq.url ~ "(?i)\.css$") {
set beresp.ttl = 3600s;
unset beresp.http.Set-Cookie;
}
}
變量:
內建變量:
req*:由客戶端發來的http請求相關;
req.http.*:請求報文各首部;
bereq.*:由varnish向backend主機發出的http請求;
beresp.*:由backend主機發來的http響應報文;
resp.*:由varnish響應給客戶端的http響應報文;
req.http.*:響應報文的各首部;
obj.*:存儲在緩存空間中的緩存對象屬性;只讀;
client.*,server.*,storage.*:可用在全部的client side的sub routines中;
自定義:set
經常使用的變量:
bereq.http.HEADERS:
bereq.request:請求方法;
bereq.url:請求的url;
bereq.proto:協議版本
bereq.backend:指明要調用的後端主機;
beresp.proto:
beresp.status:響應的狀態碼;
beresp.reason:
beresp.backend.name:
beresp.http.HEADERS:
beresp.ttl:後端服務器響應中的內容的餘下的生存時長;
obj.hits:此對象從緩存中命中的次數;
obj.ttl:對象的ttl值;
server.ip
server.hostname
server.port
req.method:請求方法;
req.url:請求的url;
緩存對象修剪的方式:purge、band
(1)purge
acl purgers {
"127.0.0.1";
"172.20.120.0"/23;
} //爲purge增長訪問控制,即只容許某些主機執行purge請求method;
sub vcl_purge {
return(synth(200,"Purged."));
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purgers) {
return(synth(405,"Purging not allowed for" + client.ip));
}
return(purge);
}
}
測試:curl -X PURGE http://172.20.120.40/night.jpg
設定多個後端服務器:
backend appsrv {
.host = "172.20.120.40";
.port = "80";
}
backend default {
.host = "172.20.120.41";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "(?i)\.php$") {
set req.backend.hint = appsrv;
} else {
set req.backend.hint = default;
}
}
後端主機的健康狀態檢測方式:
probe name {
.attribute = "value";
}
.url: 斷定BE健康與否要請求的url;
.timeout = :請求超時
.interval = :請求間隔
.window = :採樣次數
.threshold = :採樣次數中至少多少次成功,纔算是正常的健康狀態;
.request=
"GET / HTTP/1.1"
"Host: 172.20.120.41"
"Connection: close"
.expected_response = 200; :指望響應狀態碼;默認爲200;
示例1:
backend websrv1 {
.host = "172.16.100.68";
.port = "80";
.probe = {
.url = "/test1.html";
.timeout = 2s;
.interval = 1s;
.window = 8;
.threshold = 4;
}
}
backend websrv2 {
.host = "172.16.100.69";
.port = "80";
.probe = {
.url = "/test1.html";
.timeout = 2s;
.interval = 1s;
.window = 8;
.threshold = 4;
}
}
sub vcl_recv {
if (req.url ~ "(?i)\.(jpg|png|gif)$") {
set req.backend_hint = websrv1;
} else {
set req.backend_hint = websrv2;
}
}
示例2:定義後端服務負載均衡:
import directors;
sub vcl_init {
new mycluster = directors.round_robin();
mycluster.add_backend(websrv1);
mycluster.add_backend(websrv2);
}
vcl_recv {
set req.backend_hint = mycluster.backend();
}
負載均衡算法:
fallback, random, round_robin, hash
varnish命令行工具:
varnishadm -S /etc/varnish/secret -T IP:PORT :鏈接到varnish,查看其狀態;
varnish>
param.show :查看運行參數
param.set :設置運行參數
varnishtop :對varnish日誌信息排序等
varnishncsa :以apache、ncsa格式顯示日誌信息,能夠以服務模式啓動:varnishncsa.service
varnishlog :顯示原始日誌,能夠以服務模式啓動:varnishlog.service
varnishstat :顯示varnish的緩存統計信息
varnish的線程模型:
cache-worker線程
cache-main線程:此線程只有一個,用於啓動caceh;
ban luker:
acceptor:
epoll:線程池管理器
expire:清理過時緩存
varnish定義其最大併發鏈接數:線程池模型:
thread_pools:線程池個數;默認爲2;
thread_pool_max:單線程池內容許啓動的最多線程個數;
thread_pool_min
thread_pool_timeout:多於thread_pool_min的線程空閒此參數指定的時長後即被purge;