1. 程式人生 > >varnish的了解與常用配置使用

varnish的了解與常用配置使用

varnish


Varnish是一款高性能的開源HTTP加速器及反向代理服務器。

varnish架構圖:


技術分享

Varnish 與一般服務器軟件類似,分為 master 進程和 child 進程。Master 進程讀入存儲配置文件,調用合適的存儲類型,然後創建 / 讀入相應大小的緩存文件,接著 master 初始化管理該存儲空間的結構體,然後 fork 並監控 child 進程。Child 進程在主線程的初始化的過程中,將前面打開的存儲文件整個 mmap 到內存中,此時創建並初始化空閑結構體,掛到存儲管理結構體,以待分配。Child 進程分配若幹線程進行工作,主要包括一些管理線程和很多 worker 線程。

接著,開始真正的工作,varnish 的某個負責接收新 HTTP 連接線程開始等待用戶,如果有新的 HTTP 連接過來,它總負責接收,然後喚醒某個等待中的線程,並把具體的處理過程交給它。Worker 線程讀入 HTTP 請求的 URI,查找已有的 object,如果命中則直接返回並回復用戶。如果沒有命中,則需要將所請求的內容,從後端服務器中取過來,存到緩存中,然後再回復。

分配緩存的過程是這樣的:它根據所讀到 object 的大小,創建相應大小的緩存文件。為了讀寫方便,程序會把每個 object 的大小變為最接近其大小的內存頁面倍數。然後從現有的空閑存儲結構體中查找,找到最合適的大小的空閑存儲塊,分配給它。如果空閑塊沒有用完,就把多余的內存另外組成一個空閑存儲塊,掛到管理結構體上。如果緩存已滿,就根據 LRU 機制,把最舊的 object 釋放掉。

釋放緩存的過程是這樣的:有一個超時線程,檢測緩存中所有 object 的生存期,如果超初設定的 TTL(Time To Live)沒有被訪問,就刪除之,並且釋放相應的結構體及存儲內存。註意釋放時會檢查該存儲內存塊前面或後面的空閑內存塊,如果前面或後面的空閑內存和該釋放內存是連續的,就將它們合並成更大一塊內存。

整個文件緩存的管理,沒有考慮文件與內存的關系,實際上是將所有的 object 都考慮是在內存中,如果系統內存不足,系統會自動將其換到 swap 空間,而不需要 varnish 程序去控制。


配置使用varnish

CentOS7上epel源上直接安裝使用:varnish-4.0.5

[[email protected] dylan]# yum install varnish epel源

[[email protected] dylan]# cd /etc/varnish/

[[email protected] varnish]# cp varnish.params{,.bak}

[[email protected] varnish]# systemctl start varnish.service

示例:

一臺web服務器安裝httpd作為後端服務器

[[email protected] ~]# vim /var/www/html/index.html

<h1> Backend Server 1</h1>

varnish主機上編輯:

[[email protected] varnish]# vim default.vcl

backend default {

.host = "192.168.0.150"; ###後端服務器地址

.port = "80"; ###端口

[[email protected] varnish]# systemctl reload varnish.service


舉幾個常用示例:

1、.測試緩存命中情況:

[[email protected] ~]# vim /etc/varnish/default.vcl

sub vcl_deliver {

# Happens when we have all the pieces we need, and are about to send the

# response to the client.

#

# You can do accounting or modifying the final object here.

if (obj.hits>0) { ###增加

set resp.http.X-Cache = "HIT";

} else {

set resp.http.X-Cache = "Miss";

}

}

sub vcl_deliver {

# Happens when we have all the pieces we need, and are about to send the

# response to the client.

#

# You can do accounting or modifying the final object here.

if (obj.hits>0) {

set resp.http.X-Cache = "HIT via" + " " + server.ip;

} else {

set resp.http.X-Cache = "Miss via" + " " + server.ip;

}

}


###使varnishadm工具來管理

[[email protected] ]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 ###varnishadm命令

vcl.load test1 default.vcl

200

VCL compiled.

varnish> vcl.use test1

200

VCL ‘test1‘ now active


2、緩存對象修剪

acl purgers { ###添加訪問控制 varnish4.0

"127.0.0.0"/8;

"192.168.0.0"/16;

}


sub vcl_recv {

# Happens before we check if we have this in cache already.

#

# Typically you clean up the request here, removing cookies you don‘t need,

# rewriting the request, etc.

if (req.url ~"^/test.html$") {

return(pass);

}

if (req.method == "PURGE"){

if (!client.ip ~ purgers){ ###ip不屬於定義端內的返回405錯誤

return(synth(405,"Purging not allow for" + client.ip));

}

return(purge);

}

}


sub vcl_purge {

return(synth(200,"Purged,")); ###修剪

}

管理端:

varnish> vcl.load test9 default.vcl ###重新配置

200

VCL compiled.

vcl.use test9 ###使用新配置

200

VCL ‘test9‘ now active



3、###設定多個後端主機

backend default {

.host = "192.168.0.150";

.port = "80";

}

backend appsrv { ###定義一個後端主機

.host = "192.168.0.113";

.port = "80";

}

sub vcl_recv {

# Happens before we check if we have this in cache already.

#

# Typically you clean up the request here, removing cookies you don‘t need,

# rewriting the request, etc.

if (req.url ~"(?i)\.php$") {

set req.backend_hint = appsrv;

} else {

set req.backend_hint = default;

}

}

vcl.load test10 default.vcl

200

VCL compiled.

vcl.load

varnish> vcl.use test10

200

VCL ‘test10‘ now active



4、設定負載均衡效果:

Directors:

import directors; ###首先import

backend websrv1 { ###定義兩個後端主機

.host = "192.168.0.150";

.port = "80";

}

backend websrv2 {

.host = "192.168.0.115";

.port = "80";

}

sub vcl_init {

new websrvs = directors.round_robin();

websrvs.add_backend(websrv1);

websrvs.add_backend(websrv2);

}

sub vcl_recv {

set req.backend_hint = websrvs.backend();

}


管理端使用:

varnish> vcl.load test13 default.vcl

200

VCL compiled.

vcl.use test13

200

VCL ‘test13‘ now active



5、健康狀態檢測:

backend websrv1 {

.host = "192.168.0.115";

.host = "80";

.prode = {

.url = "/";

.interval = 1s;

.window = 8;

.threshold = 5;

.timeout = 2s;

}

}

.request =

"GET /HTTP/1.1"

"Host: 192.168.0.115"

"connection:Close"

.expected_response=200;


完整性示例:

vcl 4.0;

import directors;

# Default backend definition. Set this to point to your content server.

backend websrv1 {

.host = "192.168.0.150";

.port = "80";

.probe = {

.url = "/";

.interval = 2s;

.window = 5;

.threshold = 4;

}

}

backend websrv2 {

.host = "192.168.0.115";

.port = "80";

.probe = {

.url = "/";

.interval = 2s;

.window = 5;

.threshold = 4;

}

}

sub vcl_init {

new websrvs = directors.round_robin();

websrvs.add_backend(websrv1);

websrvs.add_backend(websrv2);

}


sub vcl_recv {

# if (req.url ~"(?i)\.php$") {

# set req.backend_hint = appsrv;

# } else {

set req.backend_hint = websrvs.backend();

# }

if (req.url ~"^/login") {

return(pass);

}

if (req.method == "PURGE"){

if (!client.ip ~ purgers){

return(synth(405,"Purging not allow for" + client.ip));

}

return(purge);

}

}


sub vcl_purge {

return(synth(200,"Purged,"));

}

acl purgers {

"127.0.0.0"/8;

"192.168.0.0"/16;

}


sub vcl_backend_response {

if (beresp.http.cache-control !~ "s-masage") {

if (bereq.url ~ "(?i)\.jpg$") {

set beresp.ttl = 7200s;

unset beresp.http.Set-Cookie;

}

if (bereq.url ~ "(?i)\.css$"){

set beresp.ttl = 3600s;

unset beresp.http.Set-Cookie;

}

}

}


sub vcl_deliver {

if (obj.hits>0) {

set resp.http.X-Cache = "HIT via" + " " + server.ip;

} else {

set resp.http.X-Cache = "Miss via" + " " + server.ip;

}

# if (beresp.backend.name ~ "appsrv") {

# set resp.htttp.X-Server = "appsrv";

# }

}




varnish幾個常用的命令工具:

varnishadm

varnishtop

varish log entry ranking

varnishlog

varnishlog.service

varnishncsa

varnishncsa.service

varnishstat

Varnish Cache statistics


varnish的運行時參數: 配置文件中修改全局生效

[[email protected] ~]# vim /etc/varnish/varnish.params

DAEMON_OPTS="-p thread_pools=4" ###設置線程池為4

[[email protected] ~]# systemctl restart varnish.service ###不能隨便重啟,否則緩存全部失效

[[email protected] varnish]# varnishstat ###查看狀態


附:

變量

內鍵變量:

req.*:由客戶端發來的http請求相關

req.http.*:請求報文各首部

bereq.*:由varnish向backend主機發出的http請求

bere.http.*

beresp.*:由backend主機發來的http響應報文

resp.*: 由varnish響應給client的http響應報文

resp.http.*:響應報文各首部

obj.*:存儲在緩存空間的緩存對象屬性,只讀


client.*,server.*,storage.*:可用在所有的client side 的sub riutines中

自定義: set

常用的變量:

bereq:

bereq.http.HEADERS

bereq.request:請求方法

bereq.url:請求的url

bereq.proto:協議版本

bereq.backend:指明要調用的後端主機

beresp:

beresp.proto

beresp.status:響應的狀態碼

beresp.reason

beresp.backend.name

baresp.http.HEADERA:

beresp.ttl:後端服務器響應中的內容余下的生存時長

obj:

obj.hits:此對象從緩存中命中的次數;

obj.ttl:對象的ttl值

server:

server.ip

server.hostname

req.method:請求方法

req.url:請求的url


本文出自 “11290766” 博客,請務必保留此出處http://rylan.blog.51cto.com/11290766/1957126

varnish的了解與常用配置使用