varnish與squid緩存效率對比實例

前提:安裝varnish、squid、webbench(壓測工具)php

注:varnish和squid機都未安裝其餘多餘服務,服務器綁定域名爲www.dannylinux.top  (爲同一臺服務器,測試其中一個時,另外一個服務停掉)css

(varnish和squid監聽端口都爲80,方便測試時不用配置端口轉發)html

 

軟件版本:linux

squid 3.5.20nginx

varnish 4.0.5web

 

1.varnish配置後端

#使用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 = "測試web服務器IP";   #此處實驗沒用集羣,只用了這個
.port = "80"; }

###################################################################
# 配置後端集羣事件
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頭,如經過curl -I返回頭中添加一個返回值,以下:
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.X-Cache = "cached from " + client.ip;  #若是命中,則顯示Hit from +客戶端IP
} else {
set resp.http.X-Cache = "uncached";  #未命中則顯示"Miss"    具體效果圖在最底部
}
#取消顯示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.X-restarts_count = req.restarts;
#顯示該資源緩存的時間 單位秒
set resp.http.X-Age = resp.http.Age;
#顯示該資源命中的次數
set resp.http.X-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 {
}

 

2.squid配置緩存

#
# Recommended minimum configuration:
#

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
#acl localnet src xx.xx.xx.0/24
#acl localnet src 172.31.16.128/32
acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT

#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#

forwarded_for off
via off
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost

# And finally deny all other access to this proxy
http_access allow all
#http_access deny all

# Squid normally listens to port 3128
#http_port 3128
http_port 80 accel vhost vport    #設置squid監聽端口,方便域名直接訪問
cache_peer web測試服務器IP parent 80 0 no-query no-digest originserver name=www
cache_peer_domain www www.dannylinux.top dannylinux.top
# Uncomment and adjust the following to add a disk cache directory.
cache_dir ufs /var/spool/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid

#
# Add any of your own refresh_pattern entries above these.
#


refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern -i (/cgi-bin/|\?) 0     0%      0
refresh_pattern .               0       20%     4320


refresh_pattern -i \.css$       360    50%     2880    reload-into-ims
refresh_pattern -i \.js$        1440    50%     2880    reload-into-ims
refresh_pattern -i \.html$        720   50%     1440    reload-into-ims
refresh_pattern -i \.jpg$       1440    90%     2880    ignore-reload
refresh_pattern -i \.gif$       1440    90%     2880    ignore-reload
refresh_pattern -i \.swf$       1440    90%     2880    ignore-reload
refresh_pattern -i \.jpg$       1440      50%     2880    ignore-reload
refresh_pattern -i \.png$       1440      50%     2880      ignore-reload
refresh_pattern -i \.bmp$       1440      50%     2880      ignore-reload

refresh_pattern -i \.doc$ 1440    50%     2880      ignore-reload
refresh_pattern -i \.ppt$ 1440    50%     2880      ignore-reload
refresh_pattern -i \.xls$ 1440    50%     2880      ignore-reload
refresh_pattern -i \.pdf$ 1440    50%     2880      ignore-reload
refresh_pattern -i \.rar$       1440    50%     2880      ignore-reload
refresh_pattern -i \.zip$ 1440    50%     2880      ignore-reload
refresh_pattern -i \.txt$ 1440    50%     2880      ignore-reload

 

3.測試php框架

1)varnish測試結果安全

 

 

 2)squid測試結果

 

 

4.結論

就算是排除我squid配置文件緩存沒有配置好的緣由,可是這差距還真不是通常的大啊,squid差varnish不是一點半點啊。

相關文章
相關標籤/搜索