Varnish4配置詳解

Varnish Cache是一個web應用程序加速器,也是一個HTTP反向代理軟件。放在HTTP服務器前端,css

緩存內容。採用「Visual Page Cache"技術,全部緩存數據直接從內存讀取,所以速度很是快。html

VCL4相比VCL3語法的改變點前端

  • 要在配置文件中指定版本:即在第一行寫上 vcl 4.0;web

  • vcl_fetch函數被vcl_backend_response代替,且req.*再也不適用vcl_backend_response;後端

  • 後端源服務器組director成爲varnish模塊,需import directors後再在vcl_init子例程中定義;緩存

  • vcl_error變動爲vcl_backend_error,必須使用beresp.*,而不是obj.*。bash

  • req.request變動爲req.method,obj爲只讀對象了。服務器

  • 自定義的子例程(即一個sub)不能以vcl_開頭,調用使用call sub_name;cookie

  • error()函數被synth()替代;ide

  • return(lookup)被return(hash)替代;

  • 使用beresp.uncacheable建立hit_for_pss對象;

  • 變量req.backend.healty被std.healthy(req.backend)替代;

  • 變量req.backend被req.backend_hint替代;

  • 關鍵字remove被unset替代;

  • 關鍵字"purge;"命令,已被去除。在vcl_recv使用return(purge)。

  • vcl_synth採用resp.*,而非原來的obj.* 。

更詳細改變,請查看官方文檔。

https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html


VCL內置函數

vcl_recv 在一個請求到達時調用,它的決定是否處理此請求,以及如何處理。可以使用如下幾個終止語句:

  • synth(狀態碼,緣由)

  • pass:繞過緩存,不從緩存中查詢內容也不講內容存至緩存中

  • pipe:不對客戶端進行檢查或作出任何操做,經過管道直接送日後方服務器,將數據直接經過管道在二者間傳送

  • purge 清除此對象

  • hash 在緩存中查找用戶請求的對象,若是緩存中沒有其請求的對象,後續操做極可能會將其請求的對象進行緩存;

vcl_pipe 此函數在進入pipe模式時被調用,用於將請求直接傳遞至後端主機,並將後端響應原樣返回客戶端;

  • synth(satus code,reason)

  • pipe

vcl_pass 此函數在進入pass模式時被調用,用於將請求直接傳遞至後端主機,但後端主機的響應並不緩存直接返回客戶端;

  • synth(status code,reason)

  • fetch 表示從後端獲取請求的內容,並把控制權交給vcl_fetch函數。

  • restart 重啓整個VCL,並增長重啓計數;超出max_restarts限定的最大重啓次數後將會返回錯誤信息;

vcl_hit 在執行 lookup 指令後,在緩存中找到請求的內容後將自動調用該函數;

  • restart

  • deliver 緩存此對象,並將其發送給客戶端(經由vcl_deliver);

  • synth(status code,reason)

vcl_miss 在執行 lookup 指令後,在緩存中沒有找到請求的內容時自動調用該方法,此函數可用於判斷是否須要從後端服務器獲取內容;

  • synth(status code,reason)

  • pass

  • fetch

  • restart

vcl_hash 在vcl_recv調用後爲請求建立一個hash值時,調用此函數;此hash值將做爲varnish中搜索緩存對象的key;

  • lookup 在緩存中查找用戶請求的對象,並把控制權交給vcl_miss,vcl_hit或者vcl_purge

vcl_purge pruge操做執行後調用此函數,可用於構建一個響應;

  • synth

  • restart

vcl_deliver 將在緩存中找到請求的內容發送給客戶端前調用此方法;

  • deliver

  • restart

vcl_backend_fetch 向後端主機發送請求前,調用此函數,可修改發日後端的請求;

  • fetch

  • abandon 放棄後端的請求,並生成一個錯誤

vcl_backend_response 得到後端主機的響應後,可調用此函數;

  • deliver

  • abandon

  • retry

vcl_backend_error 當從後端主機獲取源文件失敗時,調用此函數;

  • deliver

  • retry

vcl_synth

  • deliver

  • restart

vcl_init VCL加載時調用此函數,常常用於初始化varnish模塊(VMODs)

  • ok 正常返回,VCL繼續工做

vcl_fini 當全部請求都離開當前VCL,且當前VCL被棄用時,調用此函數,常常用於清理varnish模塊;

  • ok

變量類型:

wKioL1V_5lKReq-4AAHzzC0m5KE637.jpg

  • req:The request object,請求到達時可用的變量

  • bereq:The backend request object,向後端主機請求時可用的變量

  • beresp:The backend response object,從後端主機獲取內容時可用的變量

  • resp:The HTTP response object,對客戶端響應時可用的變量

  • obj:存儲在內存中時對象屬性相關的可用的變量




案例分析:

vcl 4.0;

probe backend_healthcheck {   #健康情況監測
        .url = "/health.html";
        .timeout   = 1s;
        .interval  = 10s;
        .window    = 5;
        .threshold = 2;
}
backend web2 {   #建立後端主機
    .host = "192.168.1.139";
    .port = "80";
    .probe = backend_healthcheck;
}

backend p_w_picpath1 {
    .host = "192.168.1.140";
    .port = "80";
    .probe = backend_healthcheck;
}
backend p_w_picpath2 {
    .host = "192.168.1.141";
    .port = "80";
    .probe = backend_healthcheck;
}
backend web1 {
    .host = "192.168.1.138";
    .port = "80";
    .probe = backend_healthcheck;
}

import directors;
sub vcl_init {  #建立後端主機組,基於round_robin輪轉
    new web_cluster = directors.round_robin();
    web_cluster.add_backend(web1);
    web_cluster.add_backend(web2);
    
    new img_cluster = directors.round_robin();
    img_cluster.add_backend(p_w_picpath1);
    img_cluster.add_backend(p_w_picpath2);
}

acl purgers {  #定義PURGE方法訪問來源IP
	"localhost";
	"127.0.0.1";
	"192.168.1.0"/24;
}

sub vcl_recv {
    if (req.method == "GET" && req.http.Cookie) {  #緩存帶cookie的GET請求
	return(hash);
    }
    if (req.url ~ "test.html") {  #測試頁面不緩存
	return(pass);
    }
    if (req.method == "PURGE") { #當發送PURGE請求的客戶端再也不acl中指定地址時,返回405狀態代碼,並提示Not allowed.
	if (!client.ip ~ purgers) {
	    return(synth(405,"Not allowed"));
	}
	return(hash);
    }
    if (req.http.X-Forward-For) { #爲後端主機添加X-Forward-For首部
	set req.http.X-Forward-For = req.http.X-Forward-For + "," +client.ip;
    } else {
	set req.http.X-Forward-For = client.ip;
    }
    if (req.http.host ~ "^(www.|bbs.)?mingxiao.info") {  #域名訪問策略
	set req.backend_hint = web_cluster.backend();
    }
    if (req.http.host ~ "^(img.|p_w_picpaths.)?mingxiao.info") {
	set req.backend_hint = img_cluster.backend();
    }
    return(hash);	
}

sub vcl_hit { #若是請求的是PURGE方法,命中的話返回200狀態碼。
    if (req.method == "PURGE") {
	return(synth(200,"Purged"));
    }
}

sub vcl_miss {
    if (req.method == "PURGE") {
	return(synth(404,"Not in cache"));
    }
}

sub vcl_pass {
    if (req.method == "PURGE") {
	return(synth(502,"PURGE on a passed object"));
    }
}

sub vcl_backend_response {
    if (bereq.url ~ "\.(jpg|jpeg|gif|png)$") {
	set beresp.ttl = 6000s;
    }
    if (bereq.url ~ "\.(html|css|js)$") {
	set beresp.ttl = 6000s;
    }
    if (beresp.http.Set-Cookie) {
	return(deliver);
    }
}
sub vcl_deliver { 
        if (obj.hits >0) {
                set resp.http.X-Cache="Hit from"+" "+server.ip;
        }
        else {
                set resp.http.X-Cache="Miss from"+" "+server.ip;
        }
}
相關文章
相關標籤/搜索