歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> varnish 4.0 官方文檔翻譯22-Varnish Website Performan

varnish 4.0 官方文檔翻譯22-Varnish Website Performan

日期:2017/2/27 15:47:25   编辑:Linux教程

Varnish and Website Performance

本節集中解決如何調優varnish server,同時如何使用varnish優化你的web站點.

一 共有三小節.第一小節你應該想到varnish的各種工具和功能,下一小節如何從cache中清除已經緩存的內容.清除內容是一項基本功能,因為它允許給 緩存的對象增加 TTL.TTL越大varnish保持在緩存中的時間越久,這意味著varnish處理更多的請求,只將少部分的請求傳遞到相對較慢的後端.

最後一小節,處理web內容的壓縮.當從後端獲得內容時varnish可以壓縮它,然後傳遞被壓縮後的內容.這種方式可以減少客戶現在內容的時間,從而提高你的web站點的性能.

Achieving a high hitrate

現在,varnish已經啟動和運行,你可以通過varnish訪問您的Web應用程序。除非你的應用程序是專門工作在網絡加速器之後的,你可能需要在varnish的配置或應用程序上做一些改變,以提高varnish的命中率。

varnish不會緩存你的數據,除非它是絕對肯定操作是安全的。因此,對於你為了了解varnish如何決定是否和如何來緩存頁面,我們會通過一些工具引導你,你可以找到一些工具便於理解在varnish的配置中發生了什麼。

注意,你需要一個工具來查看穿越varnish和後端之間的HTTP頭。在varnish服務器,最簡單的方法是使用varnishlog和varnishtop,但有時客戶端工具也是有意義的。這些工具是我們常用 的

Tool: varnishtop

可以使用varnishtop來找出什麼url正在被命中。varnishtop -i BereqURL 是基本的命令,向你展示varsnih發送到後端的top請求。你可以在Statistics 中查看varnishtop 用法的其他列子。

Tool: varnishlog

當你找出一個頻繁發送到後端的URL,你可以使用varnishlog查看該請求。varnishlog -q 'ReqURL ~ "^/foo/bar"' 向你展示來自客戶端匹配到/foo/bar的請求。

關於varnishlog如何工作的更多信息請查看Logging in Varnish 或者產看varnishlog的man手冊。

擴展的http頭,http://www.varnish-cache.org/trac/wiki/VCLExampleHitMissHeader

Tool: lwp-request

lwp-request 是Perl www庫中的工具。可以發送請求同時向你展示結果的基本程序。 該工具主要是查看http響應頭。很多工具都可以實現。比如linux自帶的curl工具。

# curl -I http://vg.no/
HTTP/1.1 301 Moved Permanently
Server: Apache/2.2.15 (CentOS)
X-VG-WebServer: vgphoenix-web-02
Location: http://www.vg.no/
Content-Type: text/html; charset=iso-8859-1
X-VG-SolveMe: uggc://jjj.it.ab/ynxfrgngg.ugzy
Date: Mon, 20 Jul 2015 03:28:46 GMT
Connection: keep-alive
X-Cache: HIT:40
Vary: Accept-Encoding,User-Agent
X-VG-WebCache: hmg9-varnish-01
X-Age: 46
Age: 0

還firefox的firebug工具,chrome自帶的工具都可以查看。

Cookies

默認情況,varnish不緩存從後端響應的http頭中帶有Set-Cookie的對象。如果客戶端發送的請求帶有Cookie header,varnish將忽略緩存,直接將請求傳遞到後端。

這可能是多度保守。大量站點使用Google Analytics來分析他們的流量,GA設置cookie信息來跟蹤你。該cookie被客戶端的js所使用,服務端不感興趣的。

Cookies from the client

對於大量的web應用完全清楚cookie是有意義的,除非你指定不需要忽略cookie的web站點的部分。

vcl_recv中的vcl片段將忽略cookie,除非你訪問的url中匹配到/admin/

if (!(req.url ~ "^/admin/")) {
    unset req.http.Cookie;
}

相 當簡單。然而如果你需要做些復雜的事情,像移除幾個cookie中的一個,這就變得困難了。不幸的是,varnish沒有一些好的工具來操控 cookies。我們不得不使用正則表達式來實現。如果你熟練正則表達式你將理解到發生了什麼,不然我們還是建議你先看看 pcrepattern(PCRE - Perl-compatible regular expressions),或則查看豐富的在線文檔。

我 們來看看Varnish Software(VS) 的例子。非常簡明的設置,varnish cache在前端,後端使用Drupal-based。VS使用一些跟蹤谷歌分析的cookie還有一些其他相似的工具。所有的cookie變成一個集 合,被js所使用。varnish和Drupal都不需要查看這些cookie,同時自從客戶端發送cookie到varnish,varnish將終止 正在緩存的頁面,varnish需要在VCL中丟棄不必要的cookie。

下面的VCL中我們丟棄以下劃線開始的所有cookie:

# Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");

下面的例子,我們移除所有的cookie除了叫做COOKIE1和COOKIE2,你會驚奇的發現,如此完美:

sub vcl_recv {
    if (req.http.Cookie) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(COOKIE1|COOKIE2)=", "; \1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

        if (req.http.Cookie == "") {
            unset req.http.Cookie;
        }
    }
}

一個稍微簡單的例子。使用相同的功能,能幾乎完成。從“other”cookie中過濾出“the one”我們需要的cookie,復制它給header中的另一個,然後復制回請求中,再刪除原來的cookie header。驗證請求的正確性。:

sub vcl_recv {
    # save the original cookie header so we can mangle it
    set req.http.X-Varnish-PHP_SID = req.http.Cookie;
    # using a capturing sub pattern, extract the continuous string of
    # alphanumerics that immediately follows "PHPSESSID="
    set req.http.X-Varnish-PHP_SID =
        regsuball(req.http.X-Varnish-PHP_SID, ";? ?PHPSESSID=([a-zA-Z0-9]+)( |;| ;).*","\1");
    set req.http.Cookie = req.X-Varnish-PHP_SID;
    unset req.X-Varnish-PHP_SID;
}

Varnish Cache Wiki 有更多varnish在VCL中能做什麼的驚奇例子。

Cookies coming from the backend

使用默認設置的話,後端server如果設置了Set-Cookie頭,varnish將不緩存該內容。一個hit-for-pass 的對象被創建。因此如果後端行為詭異同時設置些不需要的cookie,unset 'Set-Cookie'頭,一切將變得ok。

Cache-Control

Cache-Control頭通知緩存,如何處理該內容。Varnish關心' max-age '參數,並且是用它來計算一個對象的TTL。

因此,確定你用max-ag設置了'Cache-Control'頭。你可以看看Varnish Software的Drupalserver的響應。

$ curl -I http://www.varnish-software.com/|grep 'Cache-Control'
Cache-Control: max-age=1209600

Age

Varnish 增加'Age'頭來標明對象被varnish緩存多久。你可以使用* varnishlog -I RespHeader:^Age*來從varnishlog篩選出Age。

Pragma

HTTP 1.0server可能發送Pragma: nocache 頭。varnish忽略pragma頭。你很容易增加對該pragma頭的支持。 在vclbackendresponse

if (beresp.http.Pragma ~ "nocache") {
    set beresp.uncacheable = true;
    set beresp.ttl = 120s; # how long not to cache this url.
}

Authorization

如果varnish看到header中有'Authorization'頭,它將pass請求。如果你不需要這個頭,你可以unset。

Overriding the time-to-live (TTL)

有時候你的後端會抽下風。在varnish可以容易的重寫TTL,然後你再修復你笨重的後端。 需要在VCL中指定想要設置的對象,然後設置'beresp.ttl'

sub vcl_backend_response {
    if (bereq.url ~ "^/legacy_broken_cms/") {
        set beresp.ttl = 5d;
    }
}

Forcing caching for certain requests and certain responses

你的後端可能仍然是笨重的,且不能很好的工作,你可能想存放更多的資源到varnish。我們建議你依賴盡可能多的默認緩存規則。強制varnish在高速緩存中查找對象是很容易的,但它並不是真正的建議。

Normalizing your namespace

有 些站點是有許多域名的。 http://www.varnish-software.com/, http://varnish-software.com/ and http://varnishsoftware.com/ 都指向同一個站點。而varnish不知道他們是相同的。varnish會根據不同的域名緩存同一個對象不同的版本。你可以減緩這種情況,通過在 webserver中配置redirect或者使用下面的VCL:

if (req.http.host ~ "(?i)^(www.)?varnish-?software.com") {
    set req.http.host = "varnish-software.com";
}

HTTP Vary

HTTP Vary 並不是微不足道的概念。這是迄今為止最被誤解的HTTP標頭。

大量的響應頭告訴客戶端關於該HTTP對象是否該被傳遞。客戶端可以基於他們的參數選擇請求不同的http對象。他們的參數選擇包括像編碼和域名。當客戶端傾向於UK English時,通過Accept-Language: en-uk 表明。緩存需要保持不同的版本,通過響應中的'Vary'頭來實現。

當後端server被Vary:Accept-Language標示時,它告訴Varnish需要對每個不同的Accept-Language保存不同的版本。

如果兩個客戶端分別接受"en-us, en-uk" 和 "da, de",同時如果後端標明不同Accept-Language,varnish將緩存和提供兩個不同的版本。

請注意Vary頭需要完全匹配。因此如果Vary中是 "en-us, en-uk" 和"en-us,en-uk"(多個空格),varnish將保存同一個頁面的兩個副本。

獲得搞得命中率的同時使用Vary,關鍵是標准化後端的header。記住,哪怕是有一點不同,會導致不同的緩存條目。

下面的vcl代碼將標准化Accept-Language頭,不管"en", "de" 或者 "fr",以這個優先順序。

if (req.http.Accept-Language) {
    if (req.http.Accept-Language ~ "en") {
        set req.http.Accept-Language = "en";
    } elsif (req.http.Accept-Language ~ "de") {
        set req.http.Accept-Language = "de";
    } elsif (req.http.Accept-Language ~ "fr") {
        set req.http.Accept-Language = "fr";
    } else {
        # unknown language. Remove the accept-language header and
        # use the backend default.
        unset req.http.Accept-Language
    }
}

Vary parse errors

如果varnish解析Vary頭出錯,將會返回503網絡錯誤。或者客戶端的頭大小超過的65k. 在這種情況下SLT_Error日志會被增加。

Pitfall - Vary: User-Agent

user-Agent的陷阱。

一些應用或者應用服務器,把'Vary: User-Agent'隨著內容一起發送。這個行為通知varnish緩存每個'User-Agent'版本的單獨副本。即時是同一個浏覽器的單個補丁版本對於不同的運行操作系統也至少有10中不同的User-Agent。

如果你真的需要基於User-Agent多樣化,一定要初始化標准化header或者你能忍受varnish的命中率。使用上述代碼作為一個模板。

Copyright © Linux教程網 All Rights Reserved