varnish 4 參數配置

最近要使用varnish 4 但竟然百度、必應(沒***谷歌)都找不到靠譜的配置文件 只能忍痛看了幾天官方文檔 現在把成果分享一下

# 使用varnish版本4的格式.

vcl 4.0;

# 加載後端輪詢模塊

import directors;

#######################健康檢查策略區域###########################

# 名爲www_probe的健康檢查策略

probe www_probe {

.request =

"GET /html/test.html HTTP/1.1"    # 健康檢查url爲/html/test.html 協議爲http1.1

"Host: www.xxxxx.com"        # 訪問的域名爲www.xxxxx.com

"Connection: close";        # 檢查完關閉連接

#其他參數 如 超時時間 檢查間隔 等 均使用默認

}

##################################################################

#######################配置後端區域################################

backend backend_16 {

.host = "111.111.111.16";

.port = "80";

.probe = www_probe; # 使用名爲www_probe的健康檢查策略

}

backend backend_17 {

.host = "111.111.111.17";

.port = "80";

.probe = www_probe; # 使用名爲www_probe的健康檢查策略

}

#默認後端

backend default {

.host = "111.111.111.40";

.port = "81";

}

###################################################################

# 配置後端集羣事件

sub vcl_init {

# 後端集羣有4種模式 random, round-robin, fallback, hash

# random         隨機

# round-robin    輪詢

# fallback        後備

# hash        固定後端 根據url(req.http.url) 或 用戶cookie(req.http.cookie) 或 用戶session(req.http.sticky)(這個還有其他要配合)

# 把backend_16 和 backend_17配置爲輪詢集羣 取名爲www_round_robin

new www_round_robin = directors.round_robin();

www_round_robin.add_backend(backend_16);

www_round_robin.add_backend(backend_17);

# 把backend_16 和 backend_17配置爲隨機選擇集羣 取名爲www_random

new www_random = directors.random();

www_random.add_backend(backend_16,10);  # 設置backend_16後端的權重爲10

www_random.add_backend(backend_17,5);   # 設置backend_17後端的權重爲5

# 把backend_16 和 backend_17配置爲固定後端集羣 取名爲www_hash 在recv調用時還需要添加東西 看recv例子

new www_hash = directors.hash();

www_hash.add_backend(backend_16,1);        # 設置backend_16後端的權重爲1

www_hash.add_backend(backend_17,1);        # 設置backend_17後端的權重爲1

}

#定義允許清理緩存的IP

acl purge {

# For now, I'll only allow purges coming from localhost

"127.0.0.1";

"localhost";

}

# 請求入口 這裏一般用作路由處理 判斷是否讀取緩存 和 指定該請求使用哪個後端

sub vcl_recv {

##############################指定後端區域###########################

# 域名爲 www.xxxxx.com 的請求 指定使用名爲www_round_robin的後端集羣  在集羣名後加上 .backend() 如只使用單獨後端 直接寫後端名字即可 如 = backend_16;

if (req.http.host ~ "www.xxxxx.com") {

set req.backend_hint = www_round_robin.backend();

}

# 使用固定後端集羣例子 使用名爲www_hash的集羣

if (req.http.host ~ "3g.xxxxx.com") {

set req.backend_hint = www_hash.backend(req.http.cookie);  # 根據用戶的cookie來分配固定後端 可以指定其他分配規則

}

# 其他將使用default默認後端

#####################################################################

# 把真實客戶端IP傳遞給後端服務器 後端服務器日誌使用X-Forwarded-For來接收

if (req.restarts == 0) {

if (req.http.X-Forwarded-For) {

set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;

} else {

set req.http.X-Forwarded-For = client.ip;

}

}

# 匹配清理緩存的請求

if (req.method == "PURGE") {

# 如果發起請求的客戶端IP 不是在acl purge裏面定義的 就拒絕

if (!client.ip ~ purge) {

return (synth(405, "This IP is not allowed to send PURGE requests."));

}

# 是的話就執行清理

return (purge);

}

# 如果不是正常請求 就直接穿透沒商量

if (req.method != "GET" &&

req.method != "HEAD" &&

req.method != "PUT" &&

req.method != "POST" &&

req.method != "TRACE" &&

req.method != "OPTIONS" &&

req.method != "PATCH" &&

req.method != "DELETE") {

/* Non-RFC2616 or CONNECT which is weird. */

return (pipe);

}

# 如果不是GET和HEAD就跳到pass 再確定是緩存還是穿透

if (req.method != "GET" && req.method != "HEAD") {

return (pass);

}

# 緩存通過上面所有判斷的請求 (只剩下GET和HEAD了)

return (hash);

}

# pass事件

sub vcl_pass {

# 有fetch,synth or restart 3種模式. fetch模式下 全部都不會緩存

return (fetch);

}

# hash事件(緩存事件)

sub vcl_hash {

# 根據以下特徵來判斷請求的唯一性 並根據此特徵來緩存請求的內容 特徵爲&關係

# 1. 請求的url

# 2. 請求的servername 如沒有 就記錄請求的服務器IP地址

# 3. 請求的cookie

hash_data(req.url);

if (req.http.host) {

hash_data(req.http.host);

} else {

hash_data(server.ip);

}

# 返回lookup , lookup不是一個事件(就是 並非指跳去sub vcl_lookup) 他是一個操作 他會檢查有沒有緩存 如沒有 就會創建緩存

return (lookup);

}

# 緩存命中事件 在lookup操作後自動調用 官網文檔說 如沒必要 一般不需要修改

sub vcl_hit {

# 可以在這裏添加判斷事件(if) 可以返回 deliver restart synth 3個事件

# deliver  表示把緩存內容直接返回給用戶

# restart  重新啓動請求 不建議使用 超過重試次數會報錯

# synth    返回狀態碼 和原因 語法:return(synth(status code,reason))

# 這裏沒有判斷 所有緩存命中直接返回給用戶

return (deliver);

}

# 緩存不命中事件 在lookup操作後自動調用 官網文檔說 如沒必要 一般不需要修改

sub vcl_miss {

# 此事件中 會默認給http請求加一個 X-Varnish 的header頭 提示: nginx可以根據此header來判斷是否來自varnish的請求(就不用起2個端口了)

# 要取消此header頭 只需要在這裏添加 unset bereq.http.x-varnish; 即可

# 這裏所有不命中的緩存都去後端拿 沒有其他操作 fetch表示從後端服務器拿取請求內容

return (fetch);

}

# 返回給用戶的前一個事件 通常用於添加或刪除header頭

sub vcl_deliver {

# 例子

# set resp.http.*    用來添加header頭 如 set resp.http.xxxxx = "haha"; unset爲刪除

# set resp.status     用來設置返回狀態 如 set resp.status = 404;

# obj.hits        會返回緩存命中次數 用於判斷或賦值給header頭

# req.restarts    會返回該請求經歷restart事件次數 用戶判斷或賦值給header頭

# 根據判斷緩存時間來設置xxxxx-Cache header頭

if (obj.hits > 0) {

set resp.http.xxxxx_Cache = "cached";

} else {

set resp.http.xxxxx_Cache = "uncached";

}

#取消顯示php框架版本的header頭

unset resp.http.X-Powered-By;

#取消顯示nginx版本、Via(來自varnish)等header頭 爲了安全

unset resp.http.Server;

unset resp.http.X-Drupal-Cache;

unset resp.http.Via;

unset resp.http.Link;

unset resp.http.X-Varnish;

#顯示請求經歷restarts事件的次數

set resp.http.xxxxx_restarts_count = req.restarts;

#顯示該資源緩存的時間 單位秒

set resp.http.xxxxx_Age = resp.http.Age;

#顯示該資源命中的次數

set resp.http.xxxxx_hit_count = obj.hits;

#取消顯示Age 爲了不和CDN衝突

unset resp.http.Age;

#返回給用戶

return (deliver);

}

#處理對後端返回結果的事件(設置緩存、移除cookie信息、設置header頭等) 在fetch事件後自動調用

sub vcl_backend_response {

#後端返回如下錯誤狀態碼 則不緩存

if (beresp.status == 499 || beresp.status == 404 || beresp.status == 502) {

set beresp.uncacheable = true;

}

#如請求php或jsp 則不緩存

if (bereq.url ~ "\.(php|jsp)(\?|$)") {

set beresp.uncacheable = true;

#php和jsp以外的請求

}else{

#如請求html 則緩存5分鐘

if (bereq.url ~ "\.html(\?|$)") {

set beresp.ttl = 300s;

unset beresp.http.Set-Cookie;

#其他緩存1小時 如css js等

}else{

set beresp.ttl = 1h;

unset beresp.http.Set-Cookie;

}

}

#開啓grace模式 表示當後端全掛掉後 即使緩存資源已過期(超過緩存時間) 也會把該資源返回給用戶 資源最大有效時間爲6小時

set beresp.grace = 6h;

#返回給用戶

return (deliver);

}

#返回給用戶前的事件 可以在這裏自定義輸出給用戶的內容

sub vcl_deliver {

}


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