前提:安裝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不是一點半點啊。