Varnish的vcl子程式

来源:http://www.cnblogs.com/shenxm/archive/2017/11/05/7787841.html
-Advertisement-
Play Games

Varnish的VCL子程式 以下內容參考: http://book.varnish software.com/4.0/ VCL子進程,在其中定製Varnish的行為。VCL子常式可用於:添加自定義標頭,更改Varnish錯誤消息的外觀,在Varnish中添加HTTP重定向功能,清除內容以及定義緩存 ...


Varnish的VCL子程式


以下內容參考:
http://book.varnish-software.com/4.0/

VCL子進程,在其中定製Varnish的行為。VCL子常式可用於:添加自定義標頭,更改Varnish錯誤消息的外觀,在Varnish中添加HTTP重定向功能,清除內容以及定義緩存對象的哪些部分是唯一的。
註意:強烈建議儘可能讓預設的內置子程式。內置子程式的設計考慮到安全性,這通常意味著它們可以合理的方式處理VCL代碼中的任何缺陷。

vcl_recv

    規範化客戶端輸入
    選擇一個後端Web伺服器
    重新編寫Web應用程式的客戶端數據
    根據客戶端輸入決定緩存策略
    訪問控制列表(ACL)
    安全屏障,例如針對SQL註入攻擊
    修複錯誤,例如index.htlm- >index.html

vcl_recv是Varnish第一個VCL子進程,將客戶端請求解析為其基本數據結構之後執行。 vcl_recv有四個主要用途:

    修改客戶端數據以減少緩存的多樣性。
    決定使用哪個Web伺服器。
    根據客戶端數據決定緩存策略。
    執行特定Web應用程式所需的重寫規則。

在vcl_recv你可以執行以下終止操作:

    pass:它通過緩存查找,但它執行Varnish請求流的其餘部分。 pass不會將來自後端的響應存儲在緩存中。
    pipe:此操作創建一個全雙工管道,將客戶端請求轉發到後端,且不查看其內容。後端回覆被轉發回客戶端且不緩存其內容。由於Varnish不再嘗試將內容映射到請求上,因此任何子進程的請求發送給活動連接將被通過pipe轉發。pipe請求不會出現在任何日誌中。
    hash:它在緩存中查找請求。
    purge:它在緩存中查找請求以便刪除它。
    synth -從Varnish生成合成響應。這種合成響應通常是一個帶有錯誤信息的網頁。 synth也可以用來重定向客戶端請求。

同樣可以使用vcl_recv來設置以下安全措施。varnish不是入侵檢測系統的替代品,但仍可以用來提前阻止一些典型的攻擊。簡單訪問控制列表(ACL)也可以應用到vcl_recv上。
內建的vcl_recv子進程不會緩存所有你想要的,同時也最好不要緩存錯誤內容而是把它們發送給錯誤的用戶。
重新訪問內置的vcl_recv:

    sub vcl_recv {
        if (req.method == "PRI") {
            /* We do not support SPDY or HTTP/2.0 */
            return (synth(405));
        }
        if (req.method != "GET" &&
          req.method != "HEAD" &&
          req.method != "PUT" &&
          req.method != "POST" &&
          req.method != "TRACE" &&
          req.method != "OPTIONS" &&
          req.method != "DELETE") {
            /* Non-RFC2616 or CONNECT which is weird. */
            return (pipe);
        }
        if (req.method != "GET" && req.method != "HEAD") {
            /* We only deal with GET and HEAD by default */
            return (pass);
        }
        if (req.http.Authorization || req.http.Cookie) {
            /* Not cacheable by default */
            return (pass);
        }
        return (hash);
    }

示例:

    基本設備檢測
        sub vcl_recv {
            if (req.http.User-Agent ~ "iPad" ||
                req.http.User-Agent ~ "iPhone" ||
                req.http.User-Agent ~ "Android") {
                set req.http.X-Device = "mobile";
            } else {
                set req.http.X-Device = "desktop";
            }
        }

vcl_pass

    進入pass模式是調用
        sub vcl_pass {
            return (fetch);
        }

當上一層子進程返回pass動作後才會調用vcl_pass子進程。這動作的請求是在pass模式中設置的。vcl_pass通常作為一個重要的catch-all,服務於vcl_hit和vcl_miss執行結果。
vcl_pass可能會返回是三個動作:fetch、synth、或者是restart。當返回的的是fetch時,正在進行的請求就採用pass模式。採用pass模式從請求中抓取的對象不被緩存,但會傳遞到客戶端。synth和restart返回的動作會調用相關的子進程。
hit-for-pass

        當一個對象不應該被緩存是使用
        hit-for-pass對象取代抓取的對象
        存在TTL
    一些請求就不應該被緩存,一個典型的例子就是當一個請求頁中含有set-cookie響應頭部時,且 必須並只能把它遞送給所需的客戶端。因此你可以告訴varnish創建個hit-for-pass的對象並存儲這個對象到緩存,而不是存儲抓取的這個對象。分散式的請求被採用pass模式處理。
    當一個對象不需要被緩存是,beresp.uncacheable變數會設置為true。結果,cacher進程會保持對hit-for-pass對象的hash散列應用。這種情況下,對請求的查找操作會傳遞給hash來找個hit-for-pass對象。如此類的請求會被vclpass子進程中的pass模式給處理。
    如同其他緩存對象一樣,hit-for-pass對象也有一個TTL(生命周期)。一旦生命周期過了,這個對象就會從緩存上刪除。

vcl_backend_fetch

        sub vcl_backend_fetch {
            return (fetch);
        }
    vcl_backend_fetch 可以從vcl_miss或vcl_pass中調用。當vcl_backend_fetch從vcl_miss中調用時,抓取的對象會被緩存。如果vcl_backend_fetch被從vcl_pass中調用時,抓取的對象也不會被緩存的,即使是obj.ttl或obj.keep變數的值比0大。
    一個相關的變數是bereq.uncacheable,這個變數指示出從後端來的對象請求是否被緩存。當然從pass請求中來的對象是絕不被緩存的。
    vcl_backend_fetch有倆個可能的終端操作,fetch或abandon。fetch動作發送請求給後動,abandon動作調用vcl_synth子進程。內建vcl_bakend_fetch子進程只返回fetch動作。
    後端響應被vcl_backend-response還是vcl_backend_error處理取決於響應來之於那個服務。如果Varnish收到語法正確的HTTP響應,則Varnish將控制權交給vcl_backend_response。語法正確的HTTP響應包括HTTP 5xx錯誤代碼。如果Varnish沒有收到HTTP響應,則將控制權交給vcl_backend_error。

vcl_hash

    定義什麼是唯一的請求
    vcl_hash終是在vcl_recv後,或者另個子進程範圍hash動作關鍵詞。
    sub vcl_hash {
        hash_data(req.url);
        if (req.http.host) {
            hash_data(req.http.host);
        } else {
            hash_data(server.ip);
        }
        return (lookup);
    }

vcl_hash定義要用於緩存對象的hash key。Hash key將一個緩存對象與另一個緩存對象區分開來。預設的VCL為vcl_hash添加主機名或ip地址,同時添加請求的url給cache hash。
vcl_hash的一個用法是在cache hash上添加用戶名來識別用戶指定的數據。當然緩存用戶數據時應該謹慎進行。一個更好的選擇可能是hash每個會話緩存對象。
vcl_hash子進程返回lookup操作關鍵字。不像其他動作關鍵詞,lookup是一個操作,而不是子進程。在vcl_hash後的下個狀態取決於在緩存中lookup的查找。
當lookup操作沒能匹配到任何hash時,它會創建一個帶有busy標誌的對象並存儲在緩存中。然後,請求會被髮送到vcl_miss子進程中。一旦請求被處理busy標誌會被刪除,並從後端的響應中更新對象。
隨後遇到busy標記的對象請求將被髮送到等待列表中。這個等待名單旨在提高響應性能,這個在waiting state 選項中有解釋。
註意:一個高速緩存散列可以指代一個或多個對象變數。對象變數是基於Vary頭域的創建的。在一個緩存散列下保留多個變數是比較好的做法,而不是每個變數創建一個散列。

vcl_hit

    在lookup操作之後執行,調用vcl_hash,找到(hits)在緩存上的對象。
    sub vcl_hit {
        if (obj.ttl >= 0s) {
            // A pure unadultered hit, deliver it
            return (deliver);
        }
        if (obj.ttl + obj.grace > 0s) {
            // Object is in grace, deliver it
            // Automatically triggers a background fetch
            return (deliver);
        }
        // fetch & deliver once we get the result
        return (fetch);
    }

vcl_hit子進程通常通過調用含有deliver,restart或者synth的return()來進行終止。
如果對象的TTL+grace time沒有過時的話,返回的deliver會控制vcl_deliver。如果過時時間超過了TTL,但沒有超過TTL+grace time,deliver會調用與vcl_deliver同步的background fetch。background fetch是一種非同步調用,用來插入一個新的請求對象到緩存中。grace time會在grace模式選項中有解釋。
restart重啟傳輸,並增加重啟計數器設定值。如果重啟的次數比max_restarts設定的值要大,varnish會發出一個guru mediation的錯誤。
synth(status code,reason)返回指定狀態碼給客戶端並丟棄請求。

vcl_miss

    如果一個請求對象沒有被lookup操作找到時子進程會被調用。
    包含有是否嘗試從後端檢索文檔以及使用那個後端的策略。
    sub vcl_miss {
        return (fetch);
    }

子進程vcl_hit和vcl_miss是相關的。你很少調用他們,因為HTTP請求投吧的修改通常是在vcl_recv中進行。但是,如果你不希望發送X-Varnish頭部給後端服務,你可以把它移動動vcl_miss或vcl_pass中。基於這種情況,你可以使用unset bereq ,http,x-varnish。

vcl_deliver

    所有請求流程的公共最後退出點,除了通過vcl_pipe的請求。
    經常用於添加和移除debug-headers。
    sub vcl_deliver {
        return (deliver);
    }

vcl_deliver子進程是簡單的,同樣也是對修改varnish的輸出很有用的。如果你需要刪除一個頭部,或添加一個不應該存儲在cache中的頭部,vcl_deliver可以勝任這個工作。
在vcl_deliver中常用的且被可被修改的變數是:

    resp.http.*:發送個客戶端的頭部,它們可以被set和unset。
    resp.status:狀態碼為200,404,503等
    resp.reason:被返回給客戶端的http狀態信息
    obj.hit:在對象上的cache-hits的數。因此,0代表miss,可以評估這個變數來輕鬆地顯示響應是來自緩存命中還是未命中。
    req.restarts:在VCL中發出的重啟次數 - 如果沒有發生,則返回0。

vcl_synth

    用於在Varnish中生成內容
    錯誤消息可以在這裡創建
    其他用例:重定向用戶(301/302重定向)

vcl/default-vcl_synth.vcl:

    sub vcl_synth {
        set resp.http.Content-Type = "text/html; charset=utf-8";
        set resp.http.Retry-After = "5";
        synthetic( {"<!DOCTYPE html>
    <html>
      <head>
        <title>"} + resp.status + " " + resp.reason + {"</title>
      </head>
      <body>
        <h1>Error "} + resp.status + " " + resp.reason + {"</h1>
        <p>"} + resp.reason + {"</p>
        <h3>Guru Meditation:</h3>
        <p>XID: "} + req.xid + {"</p>
        <hr>
        <p>Varnish cache server</p>
      </body>
    </html>
    "} );
        return (deliver);
    }

你可以創建合成響應,例如,在vcl_synth上的個性化錯誤信息。調用這個子進程你可以做:
return (synth(status_code, "reason"));
註意synth不是一個關鍵字,而是個帶有參數的函數。
你必須為vcl_synth明確地返回status code和reason參數。在resp.http上設置合成響應的頭部。
註意:從 vcl/default-vcl_synth.vcl註意到 {" and "}可以用於創建多行的欄位。這個不僅限於synthetic()函數,在其他地址也可以使用。vcl_synth定義的對象絕不在緩存上存儲,對立與vcl_backend_error定義的對象。
示例:

    使用vcl_synth重定向請求
        sub vcl_recv {
            if (req.http.host == "www.example.com") {
                set req.http.location = "http://example.com" + req.url;
                return (synth(750, "Permanently moved"));
            }
        }
        sub vcl_synth {
            if (resp.status == 750) {
                set resp.http.location = req.http.location;  set resp.status = 301;
                return (deliver);
              
            }
        }

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第一個裡程碑:創建https證書 1 [root@web01 backup]# openssl req -new -x509 -nodes -out server.crt -keyout server.key 2 3 Generating a 2048 bit RSA private key 4 . ...
  • 本節來學習IIC介面下的24C02 驅動分析,本節學完後,再來學習Linux下如何使用IIC操作24C02 1.I2C通信介紹 它是由數據線SDA和時鐘SCL構成的串列匯流排,可發送和接收數據,是一個多主機的半雙工通信方式 每個掛接在匯流排上的器件都有個唯一的地址 位速在標準模式下可達 100kbit/ ...
  • 用vim打造適合自己的編輯器 一、vimrc是vim的配置文件,可以修改兩個位置 1.etc/vim/vimrc //一般配置文件都帶有rc的尾碼 2.~/.vimrc //在用戶目錄下存在的,/home/用戶名 ~/.vimrc優先順序高 進入etc/vim/vimrc vimrc配置 http:/ ...
  • 環境說明 主機為最小 安裝的centos6.9 x86_64. jumpserver安裝 第一個裡程碑:安裝git 1 [root@m01 ~]# yum -y install git 第二個裡程碑:克隆jumpserver 1 [root@m01 ~]# cd /application/ 2 3 ...
  • ...
  • 環境說明 服務端配置 第一個裡程碑:在m01上部署LNP架構 cd /server/scripts sh nginx_install.sh sh php_install.sh nginx_install.sh 腳本內容 #!/bin/bash # base setting mkdir -p /ser ...
  • 學習Linux決心計劃書 我叫耿長學,來自河南省鄧州市,經過老男孩教育運維班5個月學習後,我一定要達到的薪水目標是11000元,為了達到此目標我將採取如下10大行動或方案: 1、每天早上5:30-6:00起床,不睡懶覺,早起學習,早上起來講自己學習過的內容,多講,不停的講,練習自己的口才; 2、每天 ...
  • 博客園 首頁 新隨筆 聯繫 管理 隨筆 - 149 文章 - 28 評論 - 205 nginx簡易教程 目錄 nginx簡易教程 概述 安裝與使用 安裝 從源代碼編譯 Nginx Windows 安裝 使用 nginx 配置實戰 http反向代理配置 負載均衡配置 網站有多個webapp的配置 h ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...