溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Varnish部署

發(fā)布時(shí)間:2020-06-12 09:12:29 來(lái)源:網(wǎng)絡(luò) 閱讀:7438 作者:青衫解衣 欄目:建站服務(wù)器


上緩存服務(wù)器的目的:

1、減少clint對(duì)后端服務(wù)器的訪問(wèn)壓力。

2、在靜態(tài)資源較多的情況下,服務(wù)端可以快速對(duì)clint的訪問(wèn)做出相應(yīng)。


緩存服務(wù)器目前比較有名氣,市面上緩存代理服務(wù)器使用比較多的Varnish/squid。


squid的主要是緩存大文件。

Varnish主要緩存靜態(tài)資源,如圖片。


Varnish版本的區(qū)別:

新版本Varnish5,client/backend分離,新的vanishlog查詢語(yǔ)言,安全方面據(jù)說(shuō)有提升。


首先是必須定義版本號(hào): vcl 4.0。VMOD’s更獨(dú)立化,官方推薦是加載Standard VMOD’s(std)。


另外director已變?yōu)閂MOD,如需使用,需要import directors。


vcl_fetch函數(shù)被vcl_backend_response和vcl_backend_fetch代替,且req.*不再適用vcl_backend_response,只能使用bereq.*。


至于vcl_backend_fetch貌似沒(méi)哪個(gè)doc見(jiàn)到詳細(xì)用法。


error變更為return(synth(http_code,message)),req.backend成了req.backend_hint,req.request變更為req.method,obj為只讀對(duì)象了。


vcl_synth采用resp.*,而非原來(lái)的obj.*。


vcl_error變更為vcl_backend_error,必須使用beresp.*,而不是obj.*。


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


hit_for_pass通過(guò)set beresp.uncacheable = true;來(lái)指定。


vcl_recv必須將lookup變更返回hash,vcl_hash必須將hash變更返回lookup,vcl_pass必須將pass變更返回fetch。


req.backend.healty被std.healthy(req.backend)代替,但是設(shè)置不了grace,雞肋,被拋棄了,現(xiàn)在僅能做的就是keepalive的作用了。


req、bereq,resp、beresp之間不同,可被使用的位置不同。


server.port、client.port分別變更為std.port(server.ip)、std.port(client.ip),跟上面healthy一樣,需要import std。


session_linger變更為timeout_linger,sess_timeout變更為timeout_idle,sess_workspace被拋棄了。


remove被完全棄用了,不過(guò)我一直用unset的說(shuō)。


return(restart)變更為return(retry),vcl_backend_fetch會(huì)被使用到。


自定義sub函數(shù)不能以vcl_開(kāi)頭,調(diào)用方式call udf。



部署架構(gòu):?jiǎn)喂?jié)點(diǎn)/雙節(jié)點(diǎn)

1、如果你們的服務(wù)在云節(jié)點(diǎn)部署那久簡(jiǎn)單了,流行的云平臺(tái)都有負(fù)載均衡器(HA/LB)等等,部署2臺(tái)Varnish 掛載后端nginx 就完事了。

2、如果你們自建機(jī)房,Varnish的前端代理可以選擇(Nginx/HA),這2套開(kāi)源軟件都比較流行,做代理性能也不錯(cuò)。


下面是大致的Varnish邏輯圖:

第一種全部單節(jié)點(diǎn):

Varnish部署


第二種Varnish雙節(jié)點(diǎn),Nginx單節(jié)點(diǎn):

Varnish部署


第三種雙節(jié)點(diǎn):

Varnish部署


 Varnish的安裝上篇已經(jīng)寫過(guò),請(qǐng)參考之前的博客;


Varnish配置參數(shù):

cat /etc/sysconfig/varnish
# Maximum number of open files (for ulimit -n)  #打開(kāi)文件的最大個(gè)數(shù),limit可以修改
NFILES=131072
# Default log size is 82MB + header   #日志文件大小82M
MEMLOCK=82000
# Maximum number of threads (for ulimit -u)  #最大線程數(shù),使用unlimited變量
NPROCS="unlimited"
# Maximum size of corefile (for ulimit -c). Default in Fedora is 0  #打開(kāi)的最大核心文件數(shù),F(xiàn)edora默認(rèn)是0  
# DAEMON_COREFILE_LIMIT="unlimited"
# Set this to 1 to make init script reload try to switch vcl without restart.
# To make this work, you need to set the following variables
# explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS,
# VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE, or in short,
# use Alternative 3, Advanced configuration, below
RELOAD_VCL=1    #如果配置為1,重新load varnish配置文件vcl,varnish服務(wù)器不會(huì)重啟,可能是熱加載吧,不清楚使用默認(rèn)
# # Main configuration file. You probably want to change it :)
VARNISH_VCL_CONF=/etc/varnish/default.vcl      #Varnish默認(rèn)加載的配置文件
# VARNISH_LISTEN_ADDRESS=  #Varnish監(jiān)控的端口,改為80,修改的
VARNISH_LISTEN_PORT=80
# # Telnet admin interface listen address and port   #Varnish的管理端口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
# # Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret    #Varnish的secret文件,默認(rèn)
# # The minimum number of worker threads to start   #Varnish最小線程數(shù)
VARNISH_MIN_THREADS=50
# # The Maximum number of worker threads to start
VARNISH_MAX_THREADS=4000        #Varnish最大線程數(shù),默認(rèn)1000,不超過(guò)5000 應(yīng)該沒(méi)問(wèn)題
# # Idle timeout for worker threads
VARNISH_THREAD_TIMEOUT=120      #超時(shí)
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
VARNISH_STORAGE_SIZE=512M     #Varnish使用的空間大小默認(rèn)
# # Backend storage specification
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"   #存儲(chǔ)空間使用內(nèi)存,file是磁盤
# # Default TTL used when the backend does not specify one
VARNISH_TTL=120   #Varnish緩存時(shí)間120s


Varnish的配置文件,這塊使用的版本4.0的,其他版本還是有區(qū)別的,Varnish官網(wǎng)到5版本了。


[root@www varnish]# cat default.vcl 
#
# This is an example VCL file for Varnish.
#
# It does not do anything by default, delegating control to the
# builtin VCL. The builtin VCL is called when there is no explicit
# return statement.
#
# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/
# and http://varnish-cache.org/trac/wiki/VCLExamples for more examples.
# Marker to tell the VCL compiler that this VCL has been adapted to the
# new 4.0 format.
vcl 4.0;
#導(dǎo)入directors模塊,基于負(fù)載均衡調(diào)度,后端多個(gè)主機(jī)可以使用輪詢
import directors;
# Default backend definition. Set this to point to your content server.
#這塊以單節(jié)點(diǎn)演示
backend web1 {
    .host = "172.16.2.27";
    .port = "80";
}
#注意:用戶請(qǐng)求成功后,對(duì)請(qǐng)求的數(shù)據(jù)做處理,varnish5走緩存使用return (hash); varnish4走緩存使用 return(lookup);還是有區(qū)別的。
sub vcl_recv {    
   if (req.http.host ~ "(www.)?laiwojia.la") {  #如果請(qǐng)求的是www域名就走web1
    set req.backend_hint = web1;
}
#return(hash);#否則就走h(yuǎn)ash;這條最好寫到vcl_recv配置末尾,這是if判斷,除了www走web1,其余url都是hash,后續(xù)的測(cè)試pass的你會(huì)發(fā)現(xiàn)全是命中,注釋掉此行后才會(huì)pass
    if (req.url ~ "(?i)^/(login|admin)") {#登錄pass
    return(pass);
}
    if (req.url ~ "(?i)\.php$") {#訪問(wèn)url是php結(jié)尾走web1
        set req.backend_hint = web1;
    }
    if (req.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {#圖片走web1
    set req.backend_hint = web1;
}
####注意:varnish5.*版本使用時(shí)req.method;varnish4.*的版本使用req.request,這點(diǎn)要注意
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") {
    return (pipe);
}
if (req.http.Upgrade ~ "(?i)websocket") {
    return (pipe);
  }
if (req.method != "GET" && req.method != "HEAD") {
    return (pass);
  }
  #下面這段是我看到別人github上的資源,發(fā)現(xiàn)比較全摘錄的,壓縮、圖片、視頻流、文檔等,訪問(wèn)這些資源不保存cookie信息;
if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|otf|ogg|ogm|opus|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
    unset req.http.Cookie;
    return (hash);
  }
  #這段其實(shí)和上面的有些重復(fù),二選一或者全保留也沒(méi)錯(cuò),
if (req.http.Authorization || req.http.Cookie) {
    return (pass);
}
if (req.url ~ "test.html") { #這是上面測(cè)試的,如果請(qǐng)求的是test.html 就pass,之前return (hash),寫在上面,怎么訪問(wèn)都是hit,查看配置文件
    return (pass);
}
    return (hash);#否則就走緩存,3.0還是2.0貌似都是return (lookup),4.0 是return (hash),我嘗試些lookup 運(yùn)行發(fā)現(xiàn)報(bào)錯(cuò)
}
#對(duì)于特定類型的資源,例如公開(kāi)的圖片等,取消其私有標(biāo)識(shí),并強(qiáng)行設(shè)定其可以由varnish緩存的時(shí)長(zhǎng)
下面是服務(wù)器端對(duì)緩存服務(wù)器的響應(yīng)
sub vcl_backend_response {
    if (beresp.http.cache-control !~ "s-maxage") {
        if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
            unset beresp.http.Set-Cookie;
            set beresp.ttl = 3600s;
        }
}
     if (bereq.http.host == "(www.)?laiwojia.la") {
        if (bereq.url ~ "(?i)/api/product/hotlist"
           ||bereq.url ~ "(?i)/api/dolphin/list"
           ||bereq.url ~ "(?i)/api/product/baseInfo"
           ||bereq.url ~ "(?i)/api/product/desc"
           ||bereq.url ~ "(?i)/api/search/brandRecommendProduct"   
           ||bereq.url ~ "(?i)/cms/view/h6/headlinesList"   
           ||bereq.url ~ "(?i)/cms/view/h6/category"       
           ||bereq.url ~ "(?i)/cms/view/h6/article"       
           ||bereq.url ~ "(?i)/cms/view/h6/\w+\.html"     
           ||bereq.url ~ "(?i)/api/product/distributions")
        {
         set beresp.ttl = 300s;  //緩存時(shí)間改為5分鐘
        }
        elseif (bereq.url ~ "(?i)/api/search/searchList\?sortType=volume4sale_desc\&companyId=10\&keyword=\*\*\*\*\*\&pageSize=10" )
        {
          set beresp.ttl = 60s;  //設(shè)置為1分鐘
        }
        elseif (bereq.url ~ "(?i)/cms/view/.*/templateJS\.json" 
              ||bereq.url ~ "(?i)\.html")
        {
          set beresp.ttl = 600s;  //設(shè)置為10分鐘
        }
        elseif (bereq.url ~ "(?i)/libs/")
        {
           set beresp.ttl = 1800s;
        }
            set beresp.grace = 2m;
}
}
sub vcl_pipe {
if (req.http.upgrade) {
    set bereq.http.upgrade = req.http.upgrade;
  }
    return (pipe);
}
sub vcl_pass {
#return (pass);
}
sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
} else {
         hash_data(server.ip);
}
if (req.http.Cookie) {
    hash_data(req.http.Cookie);
  }
}
sub vcl_hit {
    if (obj.ttl >= 0s) {
    return (deliver);
}
}
sub vcl_miss {
    return (fetch);
}
#結(jié)果投遞,下面二選一都行
#響應(yīng)
#sub vcl_deliver {
#    if (obj.hits > 0) {
#       set resp.http.X-Cache = "Hit"+server.ip; //服務(wù)器響應(yīng)返回"HIT" + Varnish server ip
#     } else {
#       set resp.http.X-Cache = "Miss"; //返回未命中
#     }
#}
sub vcl_deliver {
    set resp.http.X-Age = resp.http.Age;  #響應(yīng)返回Age,
    unset resp.http.X-Age;
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT"+server.hostname;#服務(wù)器響應(yīng)只返回命中或者未命中;
    } else {
        set resp.http.X-Cache = "MISS";
    }
}


需要配置文件參考的可以直接博客回復(fù);

Varnish的常用命令:

重新載入配置文件:varnish_reload_vcl

Varnish部署


查看Varnish的日志常被緩存的資源:varnishlog

Varnish部署


另一種查看日志的姿勢(shì):varnishncsa

Varnish部署


Varnish的管理端口命令:varnishadm

Varnish部署


查看varnish命中比率:varnishstat

Varnish部署

圖標(biāo)查看varnish命中:varnishhist

Varnish部署

配置測(cè)試:

第一種測(cè)試:直接略過(guò)Varnish,直接訪問(wèn)nginx測(cè)試:

通過(guò)linux自帶命令curl訪問(wèn)

Varnish部署

查看nginx日志:

Varnish部署


第二種訪問(wèn)域名,域名解析在Varnish這臺(tái)主機(jī):

curl域名測(cè)試:

Varnish部署

查看結(jié)果:

Varnish部署


第三種:通過(guò)web 瀏覽器訪問(wèn),查看命中:

Varnish部署

第四種測(cè)試:

改變index.html文件內(nèi)容,測(cè)試結(jié)果:第一次都不會(huì)命中,第二次/第三次全部命中。

Varnish部署

配置Varnish,只要是test.html文件就pass,測(cè)試結(jié)果:

Varnish部署


以下是return (pass)和return (pipe)的區(qū)別,摘錄別人的博客:


調(diào)用 pass 函數(shù),從后端服務(wù)器調(diào)用數(shù)據(jù)。 

 

調(diào)用 pipe 函數(shù),建立客戶端和后端服務(wù)器之間的直接連接,從后端服務(wù)器調(diào)用數(shù)據(jù)。 

 

調(diào)用hash函數(shù),從緩存中查找應(yīng)答數(shù)據(jù)并返回,如果查找不到,則調(diào)用pass函數(shù)從后端服務(wù)器

調(diào)用數(shù)據(jù) 。 


http 建立連接的過(guò)程  

 

http 請(qǐng)求的類型:get post head 

先說(shuō)http建立連接的過(guò)程

 

當(dāng)瀏覽器想要獲得一個(gè)網(wǎng)頁(yè)內(nèi)容時(shí),如在瀏覽器輸入www.google.com。 

 

這時(shí)瀏覽器開(kāi)始跟服務(wù)器建立連接,先執(zhí)行三次握手,確認(rèn)建立連接。 

 

之后瀏覽器會(huì)發(fā)送請(qǐng)求,一個(gè)網(wǎng)頁(yè)包含多個(gè)內(nèi)容,如圖片,正文,html代碼,css代碼,js代碼。

如果在html 1.0版本中,請(qǐng)求一個(gè)文件是需要建立一次連接的,多個(gè)請(qǐng)求多個(gè)連接。開(kāi)銷是很大的。

而在HTML 1.1中,具有了長(zhǎng)連接的特性,允許在keep-live 時(shí)間內(nèi)保持連接,在這段時(shí)間內(nèi)無(wú)須

再建立連接就可以發(fā)送多個(gè)請(qǐng)求。 

 

請(qǐng)求完成 或 keep-live時(shí)間到限,連接斷開(kāi)。 

HTTP 請(qǐng)求的類型:

 

HTTP 請(qǐng)求的類型有幾種,下面是主要的幾種: 

  GET : 請(qǐng)求指定的頁(yè)面信息,并返回實(shí)體主體。 

 HEAD: 只請(qǐng)求頁(yè)面的首部。 

 POST: 請(qǐng)求服務(wù)器接受所指定的文檔作為對(duì)所標(biāo)識(shí)的URI的新的從屬實(shí)體。 

說(shuō)白了,請(qǐng)求一個(gè)靜態(tài)的HTML頁(yè)面就是用get類型,而如果你在新浪微博上發(fā)一條微博,其實(shí)就是post 類型。

總結(jié)來(lái)說(shuō),get是請(qǐng)求相關(guān)URI并接受服務(wù)器的返回?cái)?shù)據(jù)。為了接收數(shù)據(jù)。

post是發(fā)送數(shù)據(jù)給服務(wù)器,服務(wù)器需要對(duì)這些數(shù)據(jù)做相應(yīng)的處理。為了發(fā)送數(shù)據(jù)。

 

以上都明白的話,就可以解答這三個(gè)問(wèn)題了:

 

pass和pipe都從后端服務(wù)器取數(shù)據(jù),它們之間有什么不同呢?  

  

什么情況下用pass,什么情況下用pipe呢?  

  

什么樣的數(shù)據(jù)會(huì)被緩存在varnish中呢?  

 

問(wèn):pass和pipe都從后端服務(wù)器取數(shù)據(jù),它們之間有什么不同呢?  

答:當(dāng)vcl_recv調(diào)用 pass 函數(shù)時(shí),pass將當(dāng)前請(qǐng)求直接轉(zhuǎn)發(fā)到后端服務(wù)器。而后續(xù)的請(qǐng)求仍然

通過(guò)varnish處理。 

例如,建立了HTTP連接之后,客戶端順序請(qǐng)求 a.css 、a.png兩個(gè)文件,“當(dāng)前請(qǐng)求”指的是第一個(gè)

請(qǐng)求,即a.css,a.css被直接轉(zhuǎn)發(fā)到后端服務(wù)器,不被緩存。而后續(xù)的a.png則再由varnish來(lái)做

處理,varnish會(huì)判斷a.png 如何處理。 

總結(jié):一個(gè)連接中除了當(dāng)前請(qǐng)求,其它請(qǐng)求仍然按照正常情況由varnish處理。 

 

而pipe模式則不一樣,當(dāng)vcl_recv判斷 需要調(diào)用 pipe 函數(shù)時(shí),varnish會(huì)在客戶端和服務(wù)器之

間建立一條直接的連接 ,之后客戶端的所有請(qǐng)求都直接發(fā)送給服務(wù)器,繞過(guò)varnish,不再由varnish

檢查請(qǐng)求,直到連接斷開(kāi)。 

 

什么情況下用pass,什么情況下用pipe呢?  

答:pass 通常只處理靜態(tài)頁(yè)面。即只在GET 和 HEAD 類型的請(qǐng)求中時(shí)才適合調(diào)用pass函數(shù)。

另外,需要注意的一點(diǎn)是,pass模式不能處理POST請(qǐng)求,為什么呢?因?yàn)镻OST請(qǐng)求一般是發(fā)送

數(shù)據(jù)給服務(wù)器,需要服務(wù)器接收數(shù)據(jù),并處理數(shù)據(jù),反饋數(shù)據(jù) 。是動(dòng)態(tài)的,不作緩存。 

示例代碼如下: 

if (req.request !="GET" && req.request != "HEAD") 

{               

return (pipe);       

}       

那什么情況下用pipe?由以上陳述可以知,類型是POST時(shí)用pipe,但是也許還不太清晰。舉個(gè)例子,

當(dāng)客戶端在請(qǐng)求一個(gè)視頻文件時(shí),或者一個(gè)大的文檔,如.zip .tar 文件,就需要用pipe模式,

這些大的文件是不被緩存在varnish中的。 

 

什么樣的數(shù)據(jù)會(huì)被緩存在varnish中呢?   

答:varnish只緩存靜態(tài)數(shù)據(jù)。在網(wǎng)上搜到的varnish緩存策略,可以解答這個(gè)問(wèn)題: 

varnish緩存策略 

 

缺省是根椐后端返回的http狀態(tài)碼決定是否緩存??梢跃彺娴臓顟B(tài)碼如下: 

200    

203    

300    

301    

302    

410    

404 


這位大師的博客鏈接:http://yeelone.blog.51cto.com/1476571/772369/


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI