一、理論基礎(chǔ)
- 二種常用的開(kāi)源解決方案squid、varnish
- 條件式請(qǐng)求解決緩存與后端服務(wù)器內(nèi)容更新不匹配問(wèn)題的二種解決方案(http1.1才支持條件式請(qǐng)求,http1.0只支持過(guò)期機(jī)制)
● last modified /If-Modified-Since:基于時(shí)間戳來(lái)請(qǐng)求,客戶端會(huì)發(fā)一個(gè)首部,自從這個(gè)時(shí)間之后你有沒(méi)有改變過(guò)
● Etag(擴(kuò)展標(biāo)記)/If-None-Match:每次服務(wù)端內(nèi)容改變生成Etag發(fā)給客戶端,客戶端每次請(qǐng)求將Etag發(fā)給服務(wù)端,服務(wù)端將請(qǐng)求內(nèi)容提取出來(lái)hash出Etag 進(jìn)行比較 - 判斷過(guò)期與否:過(guò)期時(shí)間Expires
● HTTP/1.0
Expires:過(guò)期
● HTTP/1.1
Cache-Control:maxage= (所有緩存的緩存時(shí)長(zhǎng))
Cache-Control:s-maxage= (公共緩存的緩存時(shí)長(zhǎng)) - 程序架構(gòu)
● Manager進(jìn)程
● Cacher進(jìn)程,包含多種類型的線程accept、worker、expiry.......
● shared memory log:共享內(nèi)存日志(滾動(dòng)存儲(chǔ)只有80M左右大小)
查看保存導(dǎo)出類小工具:varnishlog,varnishcsa,varnishstat.....
● 配置接口:VCL(varnish configuration language) - varnish的程序環(huán)境
● /etc/varnish/varnish.params:配置varnish服務(wù)進(jìn)程的工作特性,例如監(jiān)聽(tīng)的地址和端口,緩存機(jī)制;
● /etc/varnish/default.vcl:配置各child/cache線程的緩存策略
● /usr/sbin/varnishd: 主程序
● /usr/bin/varnishadm: 管理命令接口
● Shared Memory Log 交互工具
/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishcsa
/usr/bin/varnishstat
/usr/bin/varnishtop
● 測(cè)試工具程序:/usr/bin/varnishtest
● VCL配置文件重載程序:/usr/sbin/varnish_reload_vcl - 常用狀態(tài)引擎:
● 前端線程Frontend Workthread
vcl_recv ,vcl_hash, vcl_hit, vcl_miss, vcl_purge, vcl_pipe, vcl_pass
vcl_deliver, vcl_synth
● 后端線程對(duì)服務(wù)器端Backend Workthead
vcl_backend_fetch, vcl_backedn_response, vcl_backend_error - 查看狀態(tài)引擎的一些默認(rèn)配置
● varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 連上管理程序
● help 一下,看到一些管控的子命令
● vcl.list :查看當(dāng)前生效的配置
● vcl.show boot 查看生效配置的代碼 vcl.show -v boot 查看詳細(xì)的默認(rèn)代碼 - 內(nèi)部常用變量總結(jié)(分三大類req類,be類,obj類)
● req.method :http請(qǐng)求方法(GET,HEAD,PUT,POST,TRACE,OPTIONS,DELETE
● req.http.Authorization:用戶的請(qǐng)求認(rèn)證方法
● req.url:請(qǐng)求報(bào)文中的url
● req.http.Cookie:用戶的請(qǐng)求cookie信息
● req.http.User_Agent ~ "chrome" 用戶瀏覽器類型
● req.http.Referer:防盜鏈用的,從那跳轉(zhuǎn)過(guò)來(lái)
● bereq.http.HEAERS
● berep.request:請(qǐng)求方法
● bereq.url:請(qǐng)求的url
● bereq.proto:請(qǐng)求相關(guān)的協(xié)議
● bereq.backend:指明要調(diào)用的后端主機(jī)
● beresp.http.HEADERS
● beresp.status:響應(yīng)的狀態(tài)碼
● beresp.proto:協(xié)議版本
● beresp.backend.name:BE主機(jī)的主機(jī)名
● beresp.ttl:BE主機(jī)響應(yīng)的內(nèi)容的余下的可緩存時(shí)長(zhǎng)
● obj.hits:此對(duì)象從緩存中命中的次數(shù)
● obj.ttl:對(duì)象的ttl值
● server.ip:varnish主機(jī)的IP
● server.hostname:varnish主機(jī)的hostname
● clien.ip:發(fā)請(qǐng)求至varnish主機(jī)的客戶端IP
● 用戶自定義:set ,unset
● 示例1:強(qiáng)制對(duì)某類資源的請(qǐng)求不檢查緩存

● 示例2:對(duì)于特定類型的資源,例如公開(kāi)的圖片等,取消其私有標(biāo)識(shí),并強(qiáng)行設(shè)定基可以varnish緩存的時(shí)長(zhǎng);定義在val_backend_response中

● 示例3:定義在val_recv中

二、緩存對(duì)象的修剪purge,ban等操作
- 能執(zhí)行purge操作
sub vcl_purge {
return (synth(200,"Purged"));
} - 何時(shí)執(zhí)行purge操作
sub vcl_recv{
if ( req.method == "PURGE") {
return(purge);
}
} - 對(duì)此類請(qǐng)求添加訪問(wèn)控制機(jī)制
acl purgers {
"127.0.0.0"/8;
"10.1.0.0"/16;
}
sub vcl_recv {
if (req.method == "PURGE") {
if ( !client.ip ~ purgers ) {
return(synth(405,"purging not allowed for" + client.ip));
}
return(purge);
}
} - 將同類操作ban在一起,ban的設(shè)置
● 在varnishadm命令下,用ban命令(方法1)
● ban < field><operator><arg>
示:ban req.url ~ ^/javascripts
● 在配置文件中定義,使用ban()函數(shù)(方法2)
示:if ( req.method == "BAN" ) {
ban("req.http.host ==" + req.http.host + "&&req.url ==" +req.url);
return(synth(200,"ban added"));
}
三、varnish后連多個(gè)終端,實(shí)現(xiàn)動(dòng)靜資源分離
backend default {
.host = "172.16.100.6";
.port = "80";
}
backend appsrv {
.host = "172.16.100.7";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "(?i).php$") {
set req.backend_hint = appsrv;
} else {
set req.backedn_hint = default;
}
}
四、后端同種資源服務(wù)器之間的調(diào)度
使用前先導(dǎo)入import directors
示例:
import directors:
backend server1 {
.host=
.port=
}
backend server2 {
.host =
.port =
}
sub vcl_init { #初始化一下,把同樣功能的多個(gè)服務(wù)器定義為一個(gè)組
new GROUP_NAME = directors.round_robin(); 設(shè)置調(diào)度算法
GOUP_NAME.add_backend(server1);
GOUP_NAME.add_backend(server2);
}
sub vcl_recv {
set req.backend_hint = GROUP_NAME.backend();
}基于cookie的session sticky
sub vcl_init {
new h = directors.hash();
h.add_backend(one,1); // backend 'one' with weight '1'
h.add_backend(two,1); //backend 'two' with weight '1'
}
sub vcl_recv {
set req.backend_hint = h.backend(req.http.cookie);
}后端主機(jī)健康狀態(tài)檢查
● 方法一:每個(gè)backend里都定義
backend BE_NAME {
.host =
.port =
.probe = {
.url= 對(duì)哪個(gè)url進(jìn)行檢查
.timeout= 超時(shí)時(shí)間
.interval= 每隔多長(zhǎng)時(shí)間檢查一次
.window= 基于最近的幾次進(jìn)行判斷
.threshold= 域 值 ,有幾次成功的次數(shù)
}
}
● 統(tǒng)一定義,后面各自調(diào)用
● 示例:
probe check {
.url = "/.healthcheck.html";
.window = 5;
.threshold = 4;
.interval = 2s;
.timeout = 1s;
}
backend default {
.host = "10.1.1.68";
.port = "80";
.porbe = check;
}
backend appsrv {
.host = "10.1.1.69";
.port = "80";
.probe = "check";
}
● 手動(dòng)設(shè)置為管理healthy與sick狀態(tài),在varnishadm連接命令下
backend.set_health server1 sick 設(shè)置
backend.list 查看
backend.set_health auto 再恢復(fù)原有設(shè)置設(shè)置后端的主機(jī)屬性:
backend BE_NAME {
.....
.connect_timeout = 0.5s;
.first_byte_timeout = 20s;
.between_bytes_timeout = 5s;
.max_connections = 50;
}設(shè)置修改進(jìn)程池,等相關(guān)參數(shù)的設(shè)置,并永久有效
● /etc/varnish/varnish.params 修改或者添加
● DAEMON_OPTS="-p thread_pools=4 -p thread_pool_max=10000"
● 設(shè)了四個(gè)進(jìn)程池,每個(gè)進(jìn)程池一萬(wàn)并發(fā)量
● thread_pool_min :最大空閑線程數(shù)
● thread_pool_timeout:線程空閑時(shí)長(zhǎng),并移除掉
● thread_pool_add_delay:添加新線程的延時(shí)期
● thread_pool_destroy_delay:線程超時(shí)后,再給個(gè)寬限期
五、varnish日志工具
- varnishstat
● varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss
顯示指定參數(shù)的當(dāng)前統(tǒng)計(jì)數(shù)據(jù)
● varnishstat -l -f MAIN -f MEMPOOL
列出指定配置段的每個(gè)參數(shù)的意義 - varnishtop
- varnishlog :以KV數(shù)據(jù)顯示日志信息
● varnishncsa:以傳統(tǒng)格式顯示
● varnishncsa -D -a -w /var/log/varnish/access.log 自己手動(dòng)指明日志保存到什么位置的文件中