日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux运维 第三阶段 (十八) varnish

發(fā)布時(shí)間:2025/3/17 linux 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux运维 第三阶段 (十八) varnish 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Linux運(yùn)維 第三階段 (十八) varnish

?

數(shù)據(jù):

結(jié)構(gòu)化數(shù)據(jù),RDBMS

非結(jié)構(gòu)化數(shù)據(jù),FS,存海量小文件,NASSANDFS可提供較好的性能;

?

web cache

程序具有局部性(時(shí)間局部性;空間局部性);

key-valuekeyurl訪問(wèn)路徑,hash),valueweb content);

hotpot熱點(diǎn)數(shù)據(jù);

命中率=hit/(hit+miss),文檔命中率(從文檔個(gè)數(shù)進(jìn)行衡量),字節(jié)命中率(從內(nèi)容大小進(jìn)行衡量);

緩存對(duì)象,有生命周期,定期清理;

緩存空間耗盡,LRU算法;

可緩存,不可緩存(用戶私有數(shù)據(jù));

cache is king

?

緩存的處理步驟:

接收請(qǐng)求-->解析請(qǐng)求(提取請(qǐng)求的URL及各種首部)-->查詢緩存-->新鮮度檢測(cè)-->創(chuàng)建響應(yīng)報(bào)文-->發(fā)送響應(yīng)-->記錄日志;

?

新鮮度檢測(cè)機(jī)制:

過(guò)期日期:

http/1.0Expires,時(shí)區(qū)不同則有問(wèn)題;

http/1.1Cache-Control: max-age=600,該網(wǎng)頁(yè)內(nèi)容最多存活時(shí)間,比Expires要好;

有效性再驗(yàn)證,revalidate

如果原始內(nèi)容未改變,則僅響應(yīng)首部(不附帶body部分),響應(yīng)碼304Not Modified);

如果原始內(nèi)容發(fā)生改變,則正常響應(yīng),響應(yīng)碼200

如果原始內(nèi)容消失,則響應(yīng)404,此時(shí)緩存中的cache object也應(yīng)被刪除;

?

條件式請(qǐng)求首部:

If-Modified-Since(基于請(qǐng)求內(nèi)容的時(shí)間戳作驗(yàn)證);

If-Unmodified-Since

If-Match

If-None-MatchEtag);

?

Cache-Controlcache-directive?? #(更加靈活的緩存控制機(jī)制)

cache-request-directive請(qǐng)求:

no-cache(不要緩存的實(shí)體,要求現(xiàn)在從web server上取);

max-age(只接受Age值小于max-age值,并且沒(méi)有過(guò)期的對(duì)象);

max-stale(可以接受過(guò)去的對(duì)象,但過(guò)期時(shí)間必須小于max-stale值);

min-fresh(接受其新鮮生命期大于其當(dāng)前Agemin-fresh值之和的緩存對(duì)象);

no-store;

no-transform;

only-if-cached;

cache-extension;

cache-response-directive響應(yīng):

public(可以用cached內(nèi)容回應(yīng)任何用戶);

private(只能用緩存內(nèi)容回應(yīng)先前請(qǐng)求該內(nèi)容的那個(gè)用戶);

no-cache(可以緩存,但只有在跟web server驗(yàn)證其有效后,才能返回給client);

max-age(本響應(yīng)包含的對(duì)象的過(guò)期時(shí)間);

ALL:no-store(不允許緩存);

no-transform;

must-revalidate;

proxy-revalidate;

s-maxage;

cache-extenion;

?

?

HTTP Expiration

緩存過(guò)期,則一定會(huì)到原始server上去取,但原始server上的內(nèi)容未必發(fā)生改變;

?

HTTP validation

Last-Modified/If-Modified-Since

Etag/If-None-Match

?

兩者結(jié)合:

you can combie HTTP headers the way you want,Expiration wins over Validation

?

常見(jiàn)的緩存服務(wù)器開(kāi)源解決方案:

varnish VS squid(類(lèi)似nginx VS httpd);

?

CDNGSLB,緩存路由協(xié)議;大公司,全國(guó)各機(jī)房自建CDN;中小公司租用 第三方CDN,帝聯(lián)、藍(lán)訊等);

?

http://www.varnish-cache.org/

?

varnish architecture

?

DSLdomain specific language

VCLvarnish configuration language,緩存策略配置接口,基于域的簡(jiǎn)單編程語(yǔ)言;

管理進(jìn)程(編譯vcl并應(yīng)用新配置,監(jiān)控varnish,初始化varnishCLI接口);

child/cacheacceptor(接收新的連接請(qǐng)求);worker threads(處理用戶請(qǐng)求);Expiry(清理緩存中的過(guò)期對(duì)象));

單進(jìn)程多線程;

日志(shared memory log,默認(rèn)90M,分為兩部分,前一部分是計(jì)數(shù)器,后一部分是請(qǐng)求相關(guān)的數(shù)據(jù));

?

內(nèi)存分配和回收:

malloc()free()?? #(這兩種效率不高);

jemalloc?? #General-purpose scalable concurrent malloc(3) implementation,更高效)

?

varnish如何存儲(chǔ)緩存對(duì)象:

方式一:file(單個(gè)文件;不支持持久機(jī)制;適用于大量文件,最好用pci-e disk;與nginx緩存不同,varnish將所有緩存對(duì)象存放在單個(gè)文件中,varnish自己管理這個(gè)文件,varnish在這個(gè)文件內(nèi)部組織出專用的FSvarnish自己識(shí)別每一個(gè)緩存對(duì)象從哪開(kāi)始到哪結(jié)束,名字等元數(shù)據(jù),varnish用于緩存的這一單個(gè)文件是獨(dú)立自治的王國(guó);varnish服務(wù)在運(yùn)行過(guò)程中不能隨便重啟,否則緩存全部失效);

注:

nginx將緩存對(duì)象放在disk中,key在內(nèi)存里,nginx緩存在定義時(shí)有多級(jí)緩存目錄,levels=1:2:2,目錄下放緩存對(duì)象,每一個(gè)緩存對(duì)象用一個(gè)文件來(lái)存,因此會(huì)有很多文件描述符inode

方式二:malloc(在內(nèi)存中存放緩存對(duì)象,時(shí)間久了有內(nèi)存碎片);

方式三:persistent(基于文件的持久存儲(chǔ),實(shí)驗(yàn)階段,有io問(wèn)題,最好用SSD disk);

?

配置varnish的三種接口:

1varnishd應(yīng)用程序的命令行參數(shù):

監(jiān)聽(tīng)的socket,使用的存儲(chǔ)類(lèi)型等額外的配置參數(shù);

-p param=value

-r param,param,……?? #(設(shè)定只讀參數(shù)列表)

2-p選項(xiàng)指明的參數(shù),run-time運(yùn)行時(shí)參數(shù),可在程序運(yùn)行時(shí),通過(guò)其CLI進(jìn)行配置;

3vcl,配置緩存系統(tǒng)的緩存機(jī)制,通過(guò)vcl配置文件進(jìn)行配置,先編譯(依賴c compilegcc),后應(yīng)用,/etc/varnish/default.vcl

?

?

?

]#yum -y install varnish?? #2 version-->3的配置不兼容,3-->4兼容)

Package(s)data still to download: 455 k

(1/3):jemalloc-3.6.0-1.el6.x86_64.rpm??????????????????????????????????????????????????| 100 kB???? 00:00????

(2/3):varnish-2.1.5-6.el6.x86_64.rpm???????????????????????????????????????????????????| 264 kB???? 00:00????

(3/3):varnish-libs-2.1.5-6.el6.x86_64.rpm??????????????????????????????????????????????|? 90 kB???? 00:00???

?

]#varnishd -V

varnishd(varnish-2.1.5 SVN )

Copyright(c) 2006-2009 Linpro AS / Verdens Gang AS

?

]#varnishd -h?? #(默認(rèn)listen 6081/60826081服務(wù)端口,6082admin端口,haproxy默認(rèn)5000

??? -a address:port????????????? # HTTP listen address and port

??? -b address:port????????????? # backend address and port

???????????????????????????????? #??? -b <hostname_or_IP>

???????????????????????????? ????#???-b '<hostname_or_IP>:<port_or_service>'

??? -f file????????????????????? # VCL script

??? -s kind[,storageoptions]???? # Backend storage specification

???????????????????????????????? #?? -s malloc

???????????????????????????????? #?? -s file?[default: use /tmp]

???????????????????????????????? #?? -s file,<dir_or_file>

???????????????????????????????? #?? -s file,<dir_or_file>,<size>

???????????????????????????????? #?? -sfile,<dir_or_file>,<size>,<granularity>

??? -S secret-file?????????????? # Secret file for CLIauthentication

??? -T address:port????????????? # Telnet listen address and port

?

]#rpm -ql varnish??

/etc/rc.d/init.d/varnish

/etc/rc.d/init.d/varnishlog

/etc/rc.d/init.d/varnishncsa

/etc/sysconfig/varnish

/etc/varnish

/etc/varnish/default.vcl

/usr/bin/varnishadm

/usr/bin/varnishhist

/usr/bin/varnishlog

/usr/bin/varnishncsa

/usr/bin/varnishreplay

/usr/bin/varnishsizes

/usr/bin/varnishstat

/usr/bin/varnishtest

/usr/bin/varnishtop

/usr/sbin/varnish_reload_vcl

/usr/sbin/varnishd

/usr/share/doc/varnish-2.1.5

……

?

注:

centos7中:

epel源的varnish4.0.3

通過(guò)systemctl控制應(yīng)用啟動(dòng)和關(guān)閉;

/etc/varnish/varnish.params,用于在啟動(dòng)varnish時(shí)傳遞運(yùn)行的參數(shù),不通過(guò)此文件則要在命令行中指定;

/usr/lib/systemd/system/varnish.service中定義EnvironmentFile=/etc/varnish/varnish.params,通過(guò)定義EnvironmentFile方式加載參數(shù),沒(méi)有腳本了;

ExecStart=/usr/sbin/varnishd

centos6中:

epel源的varnish2.1.5

/etc/sysconfig/varnish,大多數(shù)程序是通過(guò)腳本傳遞參數(shù);

?

]#yum -y install httpd

]#for i in {1..10} ; do echo "page $i on web" > /var/www/html/test$i.html ; done

]#chkconfig --list httpd?? #centos7#systemctl start httpd.service#systemctl enable httpd.service#systemctl is-enabled httpd.service

]#/etc/init.d/httpd start

]#ss -tnl | grep :80

LISTEN???? 0?????511?????????????????????:::80????????????????????? :::*??

?

]#vim /etc/sysconfig/varnish?? #(或/etc/sysconfig/varnish不動(dòng),更改/etc/varnish/default.vcl中的backend_default {

backenddefault {

? .host = "127.0.0.1";

? .port = "80";

}

);

VARNISH_TTL=120?? #varnish連接backend servertimeout

DAEMON_OPTS="-a:6081 \

???????????? -T localhost:6082 \

????? ???????-b localhost:80 \

???????????? -u varnish -g varnish \

???????????? -sfile,/var/lib/varnish/varnish_storage.bin,1G"

#DAEMON_OPTS="-a${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \

#???????????? -f ${VARNISH_VCL_CONF} \

#???????????? -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT}\

#???????????? -t ${VARNISH_TTL} \

#???????????? -w${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \

#???????????? -u varnish -g varnish \

#???????????? -S ${VARNISH_SECRET_FILE} \

#???????????? -s ${VARNISH_STORAGE}"

?

]#/etc/init.d/varnish restart

Stoppingvarnish HTTP accelerator:???????????????????????? [? OK? ]

Startingvarnish HTTP accelerator:???????????????????????? [? OK? ]

]#ss -tnl | egrep "6081|6082"

LISTEN???? 0?????1024???????????????????? :::6081??????????????????? :::*????

LISTEN???? 0?????1024?????????????????????*:6081???????????????????? *:*????

LISTEN???? 0?????10???????????????127.0.0.1:6082????????????????????*:*????

LISTEN???? 0?????10??????????? ??????????::1:6082??????????????????? :::*??

?

?

]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082?? #(管理接口)

help

200377????

help[command]

ping[timestamp]?? #(查看主機(jī)狀態(tài))

authresponse

quit

banner

status?? #(查看child進(jìn)程狀態(tài))

start?? #start,stop用于啟停child進(jìn)程)

stop

stats

vcl.load <configname> <filename>?? #(裝載vcl文件并編譯,configname是自定義的)

vcl.inline <configname> <quoted_VCLstring>

vcl.use <configname>

vcl.discard <configname>

vcl.list

vcl.show <configname>

param.show [-l] [<param>]

param.set <param> <value>

purge.url <regexp>

purge<field> <operator> <arg> [&& <field><oper> <arg>]...

purge.list

?

ping

20019?????

PONG1497921153 1.0

?

status

20022?????

Childin state running

?

vcl.list?? #active為當(dāng)前在用)

20023?????

active????????? 2 boot

?

vcl.load test /etc/varnish/default.vcl

20013?????

VCLcompiled.

?

vcl.use test

2000??????

?

vcl.list

20046?????

available?????? 1 boot

active????????? 1 test

?

vcl.useboot

2000??????

?

vcl.list

20046?????

active????????? 2 boot

available?????? 0 test

?

vcl.discard test

2000??????

?

vcl.list

20023?????

active????????? 2 boot

?

param.show?? #(顯示運(yùn)行時(shí)參數(shù),常用的有:thread_pool_min,thread_pool_max,thread_pools,該server的并發(fā)連接數(shù)為thread_pools*thread_pool_max;若不想讓這些運(yùn)行時(shí)參數(shù)被更改,可在啟動(dòng)時(shí)用-r指明是只讀,

2002413???

acceptor_sleep_decay?????? 0.900000 []

acceptor_sleep_incr??????? 0.001000 [s]

acceptor_sleep_max???????? 0.050000 [s]

auto_restart?????????????? on [bool]

ban_lurker_sleep?????????? 0.000000 [s]

between_bytes_timeout????? 60.000000 [s]

cache_vbe_conns??????????? off [bool]

cc_command???????????????? "exec cc -fpic -shared-Wl,-x -o %o %s"

cli_buffer?????????????? ??8192 [bytes]

cli_timeout??????????????? 10 [seconds]

clock_skew???????????????? 10 [s]

connect_timeout??????????? 0.400000 [s]

critbit_cooloff??????????? 180.000000 [s]

default_grace????????????? 10 [seconds]

default_ttl??????????????? 120 [seconds]

diag_bitmap??????????????? 0x0 [bitmap]

err_ttl??????????????????? 0 [seconds]

esi_syntax???????????????? 0 [bitmap]

expiry_sleep?????????????? 1.000000 [seconds]

fetch_chunksize??????????? 128 [kilobytes]

first_byte_timeout???????? 60.000000 [s]

group??????? ??????????????varnish (498)

http_headers?????????????? 64 [header lines]

http_range_support???????? off [bool]

listen_address???????????? :6081

listen_depth?????????????? 1024 [connections]

log_hashstring???????????? off [bool]

log_local_address????????? off [bool]

lru_interval?????????????? 2 [seconds]

max_esi_includes?????????? 5 [includes]

max_restarts?????????????? 4 [restarts]

overflow_max?????????????? 100 [%]

ping_interval????????????? 3 [seconds]

pipe_timeout?????????????? 60 [seconds]

prefer_ipv6? ??????????????off [bool]

purge_dups???????????????? on [bool]

rush_exponent????????????? 3 [requests per request]

saintmode_threshold??????? 10 [objects]

send_timeout?????????????? 600 [seconds]

sess_timeout?????????????? 5 [seconds]

sess_workspace??????? ?????65536 [bytes]

session_linger???????????? 50 [ms]

session_max??????????????? 100000 [sessions]

shm_reclen???????????????? 255 [bytes]

shm_workspace????????????? 8192 [bytes]

syslog_cli_traffic???????? on [bool]

thread_pool_add_delay????? 20 [milliseconds]

thread_pool_add_threshold? 2 [requests]

thread_pool_fail_delay???? 200 [milliseconds]

thread_pool_max??????????? 1000 [threads]

thread_pool_min??????????? 1 [threads]

thread_pool_purge_delay??? 1000 [milliseconds]

thread_pool_stack????????? unlimited [bytes]

thread_pool_timeout??????? 120 [seconds]

thread_pools?????????????? 2 [pools]

thread_stats_rate????????? 10 [requests]

user?????????????????????? varnish (498)

vcl_trace????????????????? off [bool]

waiter???????????????????? default (epoll, poll)

?

param.show -l?? #(顯示更詳細(xì)的信息)

……

?

param.show thread_pools

2001111???

thread_pools?????????????? 2 [pools]

?????????????????????????? Default is 2

?????????????????????????? Number of workerthread pools.

??????????????????????????

?????????????????????????? Increasing number ofworker pools decreases lock

?????????????????????????? contention.

??????????????????????????

?????????????????????????? Too many pools wasteCPU and RAM resources, and

?????????????????????????? more than one poolfor each CPU is probably

??? ???????????????????????detrimal to performance.

??????????????????????????

?????????????????????????? Can be increased onthe fly, but decreases require

?????????????????????????? a restart to takeeffect.

??????????????????????????

???????????????????? ??????NB: This parameter may take quite sometime to

?????????????????????????? take (full) effect.

??????????????????????????

?????????????????????????? NB: We do not knowyet if it is a good idea to

?????????????????????????? change thisparameter, or if the default value is

?????????????????????????? even sensible.? Caution is advised, and feedback

?????????????????????????? is most welcome.

?

vcl.show boot?? #(顯示vcl文件編譯前的內(nèi)容)

?

注:

4版本的管理命令行下還有:

panic.show

storage.list

backend.list

backend.set_healthbackend server從離線-->上線);

ban.list(清理緩存中的緩存對(duì)象,根據(jù)表達(dá)式清理某一類(lèi)緩存對(duì)象,默認(rèn)緩存對(duì)象過(guò)期則會(huì)清理);

?

?

]#varnishlog?? #log有關(guān),在宿主機(jī)上訪問(wèn)http://10.230.32.208:6081/test6.html[-i tag] [-I regexp] (include regular express); [-X regexp](exclude regular express) [-x tag]

?? 13 SessionOpen? c 192.168.2.14 2665 :6081

?? 13 ReqStart???? c 192.168.2.14 2665 1994176375

?? 13 RxRequest??? c GET

?? 13 RxURL??????? c /test6.html

?? 13 RxProtocol?? c HTTP/1.1

?? 13 RxHeader???? c Host: 10.230.32.208:6081

?? 13 RxHeader???? c Connection: keep-alive

?? 13 RxHeader???? c Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

?? 13 RxHeader???? c User-Agent: Mozilla/5.0 (Windows NT 6.1;WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36

?? 13 RxHeader???? c Accept-Encoding: gzip,deflate,sdch

?? 13 RxHeader???? c Accept-Language: zh-CN,zh;q=0.8

?? 13 VCL_call???? c recv

?? 13 VCL_return?? c lookup

?? 13 VCL_call???? c hash

?? 13 VCL_return?? c hash

?? 13 VCL_call???? c miss

?? 13 VCL_return?? c fetch

?? 14 BackendOpen? b default 127.0.0.1 45242 127.0.0.1 80

?? 13 Backend????? c 14 default default

?? 14 TxRequest??? b GET

?? 14 TxURL??????? b /test6.html

?? 14 TxProtocol?? b HTTP/1.1

?? 14 TxHeader???? b Host: 10.230.32.208:6081

?? 14 TxHeader???? b Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

?? 14 TxHeader???? b User-Agent: Mozilla/5.0 (Windows NT 6.1;WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36

……

?

]#varnishncsa?? #log有關(guān),與combined接近,訪問(wèn)http://10.230.32.208:6081/test8.html

192.168.2.14- - [07/Jul/2017:10:01:19 +0800] "GEThttp://10.230.32.208:6081/favicon.ico HTTP/1.1" 404 290 "-""Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/28.0.1500.72 Safari/537.36"

192.168.2.14- - [07/Jul/2017:10:01:19 +0800] "GEThttp://10.230.32.208:6081/favicon.ico HTTP/1.1" 404 290 "-""Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/28.0.1500.72 Safari/537.36"

?

]#varnishtop?? #top

?

]#varnishstat?? #statistics,)

]#varnishstat -l?? #-l ?# Lists the available fields to use with the-f option

Varnishstat-f option fields:

Fieldname?????????? Description

----------?????????? -----------

client_conn????????? Client connections accepted

client_drop????????? Connection dropped, no sess/wrk

client_req?????????? Client requests received

cache_hit??????????? Cachehits

cache_hitpass??????? Cache hits for pass

cache_miss?????????? Cache misses

backend_conn???????? Backend conn. success

backend_unhealthy??? Backend conn. not attempted

backend_busy???????? Backend conn. too many

backend_fail???????? Backend conn. failures

backend_reuse??????? Backend conn. reuses

backend_toolate????? Backend conn. was closed

backend_recycle????? Backend conn. recycles

backend_unused??????Backend conn. unused

fetch_head?????????? Fetch head

fetch_length???????? Fetch with Length

fetch_chunked??????? Fetch chunked

fetch_eof??????????? Fetch EOF

fetch_bad??????????? Fetch had bad headers

fetch_close????????? Fetch wanted close

fetch_oldhttp??????? Fetch pre HTTP/1.1 closed

fetch_zero?????????? Fetch zero len

fetch_failed???????? Fetch failed

n_sess_mem?????????? N struct sess_mem

n_sess?????????????? N struct sess

n_object???????????? N struct object

n_vampireobject????? N unresurrected objects

n_objectcore???????? N struct objectcore

n_objecthead???????? N struct objecthead

n_smf??????????????? N struct smf

n_smf_frag?????????? N small free smf

n_smf_large????????? N large free smf

n_vbe_conn?????????? N struct vbe_conn

n_wrk?? ?????????????N worker threads

n_wrk_create???????? N worker threads created

n_wrk_failed???????? N worker threads not created

n_wrk_max??????????? N worker threads limited

n_wrk_queue????????? N queued work requests

n_wrk_overflow?????? N overflowed work requests

n_wrk_drop?????????? N dropped work requests

n_backend??????????? N backends

n_expired??????????? N expired objects

n_lru_nuked????????? N LRU nuked objects

n_lru_saved????????? N LRU saved objects

n_lru_moved????????? N LRU moved objects

n_deathrow?????????? N objects on deathrow

losthdr????????????? HTTP header overflows

n_objsendfile??????? Objects sent with sendfile

n_objwrite?????????? Objects sent with write

n_objoverflow??????? Objects overflowing workspace

s_sess?????????????? Total Sessions

s_req??????????????? Total Requests

s_pipe?????????????? Total pipe

s_pass?????????????? Total pass

s_fetch????????????? Total fetch

s_hdrbytes?????????? Total header bytes

s_bodybytes????????? Total body bytes

sess_closed????????? Session Closed

sess_pipeline??????? Session Pipeline

sess_readahead?????? Session Read Ahead

sess_linger????????? Session Linger

sess_herd??????????? Session herd

shm_records????????? SHM records

shm_writes?????????? SHM writes

shm_flushes???? ?????SHM flushes due to overflow

shm_cont???????????? SHM MTX contention

shm_cycles?????????? SHM cycles through buffer

sm_nreq????????????? allocator requests

sm_nobj????????????? outstanding allocations

sm_balloc??????????? bytes allocated

sm_bfree????? ???????bytes free

sma_nreq???????????? SMA allocator requests

sma_nobj???????????? SMA outstanding allocations

sma_nbytes?????????? SMA outstanding bytes

sma_balloc?????????? SMA bytes allocated

sma_bfree??????????? SMA bytes free

sms_nreq???????????? SMS allocator requests

sms_nobj???????????? SMS outstanding allocations

sms_nbytes?????????? SMS outstanding bytes

sms_balloc?????????? SMS bytes allocated

sms_bfree??????????? SMS bytes freed

backend_req????????? Backend requests made

n_vcl??????????????? N vcl total

n_vcl_avail????????? N vcl available

n_vcl_discard??????? N vcl discarded

n_purge????????????? N total active purges

n_purge_add????????? N new purges added

n_purge_retire?????? N old purges deleted

n_purge_obj_test???? N objects tested

n_purge_re_test????? N regexps tested against

n_purge_dups???????? N duplicate purges removed

hcb_nolock?????????? HCB Lookups without lock

hcb_lock???????????? HCB Lookups with lock

hcb_insert?????????? HCB Inserts

esi_parse??????????? Objects ESI parsed (unlock)

esi_errors?????????? ESI parse errors (unlock)

accept_fail????????? Accept failures

client_drop_late???? Connection dropped late

uptime?????????????? Client uptime

backend_retry??????? Backend conn. retry

dir_dns_lookups????? DNS director lookups

dir_dns_failed?????? DNS director failed lookups

dir_dns_hit????????? DNS director cached lookups hit

dir_dns_cache_full?? DNS director full dnscache

fetch_1xx??????????? Fetch no body (1xx)

fetch_204??????????? Fetch no body (204)

fetch_304??????????? Fetch no body (304)

]#varnishstat -f cache_hit?? #-f field_list # Comma separatedlist of fields to display.

?

?

vcl state engine

?

vcl_recv

vcl_hash

vcl_hit,vcl_miss

vcl_fetch

vcl_deliver

vcl_pipe?? #當(dāng)檢測(cè)到client請(qǐng)求不是gethead時(shí),也不是正常http的方法,用vcl_pipe直接扔給backend server,一手托兩家;

vcl_pass

vcl_error?? # varnish在前端生成錯(cuò)誤頁(yè)面信息,用于refuse request或其它異常狀態(tài)由varnish合成錯(cuò)誤頁(yè)面);

Verion4還有:

vcl_purge

vcl_backend_fetch

vcl_backend_response

vcl_synth

vcl_backend_error

?

注:

iptables

prerouting-->input-->forwar-->postrouting

output-->postrouting

?

各引擎間有一定程度的相關(guān)性,前一個(gè)engine若有多個(gè)下游engine,則上游engine需用return指明要轉(zhuǎn)移的下游engine

?

the vcl finite state machine

1comment//,#,/*……*/,這些注釋信息可被編譯器忽略;

2sub $NAME { },用于定義子例程;

3、不支持循環(huán);

4、有眾多內(nèi)置的變量,變量的可調(diào)用位置與state engine有密切相關(guān)性;

5、支持終止語(yǔ)句,return (action),沒(méi)有返回值;

6、“域”專用;

7、操作符,=,==,~,!,&&,||

?

條件判斷語(yǔ)句:

if (CONDITION) {

} else {

}

?

變量賦值:

set name=value

unset name=value

?

?

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.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") {

???????? return (pipe);

}

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

???????? return (pass);

}

if (req.http.Authorization || req.http.Cookie) {

???????? return (pass);

}

return (lookup);

?

hash_data (req.url);

if (req.http.host) {

???????? hash_data(req.http.host);

} else {

???????? hash_data(server.ip);

}

return (hash);

?

return (deliver);

?

return (fetch);

?

if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {

???????? set beresp.ttl = 120 s;

???????? return (hit_for_pass);

}

return (deliver);

?

state engine workflow(V3)

workflow1:

vcl_recv-->vcl_hash-->vcl_hit->vcl_deliver

?

workflow2:

vcl_recv-->vcl_hash-->vcl_miss-->vcl_fetch-->vcl_deliver

?

workflow3:

vcl_recv-->vcl_pass-->vcl_fetch-->vcl_deliver

?

workflow4:

vcl_recv-->vcl_pipe

?

variable availability in VCL:

varnish中的內(nèi)置變量:

req?? #req.http.HEADERreq.methodreq.protoreq.urlreq.ttl

resp?? #resp.http.HEADERresp.protoresp.reasonresp.status

bereq?? #backendbereq.http.HEADERSvarnish發(fā)往backend server請(qǐng)求報(bào)文的指定首部;bereq.request請(qǐng)求方法;bereq.urlbereq.protobereq.backend指明要調(diào)用的后端主機(jī);

beresp?? #beresp.protbackendserver響應(yīng)時(shí)的協(xié)議版本;beresp.status響應(yīng)狀態(tài)碼;beresp.reason原因短語(yǔ);beresp.backend.ipberesp.backend.nameberesp.http.HEADERbackend server響應(yīng)的報(bào)文首部;beresp.ttlbackend server響應(yīng)的內(nèi)容余下的生存時(shí)長(zhǎng);

client

now

obj?? #obj.ttl,對(duì)象的ttl值;obj.hits,此對(duì)象從緩存中命中的次數(shù);

server?? #server.hostnameserver.ip

storage?? #storage.<name>.free_spacestorage.<name>.used_spacestorage.<name>.happyhealth status);

functions

?

?

default.vclbackend server定義:

backend NAME {

???????? .ATTRIBUTE = "VALUE";

???????? .host = "IP_ADDRESS";

???????? .port = "PORT";

???????? .probe = {

?????????????????? .url ="/test1.html";

???????? }

}

?

注:

.probe對(duì)be作健康狀態(tài)檢測(cè):

probe NAME {

???????? .ATTRIBUTE = "VALUE";

???????? .url = "/test.html";

???????? .expected_response = 200;?? #期望的響應(yīng)狀態(tài)碼,默認(rèn)200

}

舉例:

backend websrv1 {

???????? .host = "192.168.239.20";

???????? .port = "80";

???????? .probe = {

?????????????????? .url = "/test.html";

???????? }

}

backend websrv2 {

???????? .host = "192.168.239.21";

???????? .port = "80";

???????? .probe = {

?????????????????? .url = "/test.html";

???????? }

}

sub vcl_recv{

???????? if (req.url ~ "(?i)\.(jpg|png|gif)$") {

?????????????????? set req.backend_hint = websrv1;

???????? } else {

?????????????????? set req.backend_hint = websrv2;

???????? }

}

?

LB算法:

fallback

random

round_robin?? #是對(duì)整個(gè)資源輪循,如依次請(qǐng)求/test1.html,/test2.html,/test3.html,若始終訪問(wèn)/test1.html,則始終從一個(gè)backend server返回;

hash;

舉例:

backend websrv1 {

……

}

backend websrv2 {

……

}

import directors;

sub vcl_init {

???????? new mycluster = directors.round_robin();

???????? mycluster.add_backend(websrv1);

???????? mycluster.add_backend(websrv2);

}

subvcl_recv {

???????? set req.backend_hint = mycluster.backend();

}

?

注:

#man vmod_directors

#curl http://VARNISH_SERVER:6082/test{1,2,3}.html

?

?

?

例:

給響應(yīng)給client的報(bào)文添加自定義首部X-Cache,在vcl_deliver中定義:

subvcl_deliver {

??????? if (obj.hits > 0) {

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

??????? } else {

??????????????? set resp.http.X-Cache = "MISS";

??????? }

}

?

vcl.list

20023?????

active????????? 1 boot

?

vcl.load test /etc/varnish/test.vcl

20013?????

VCLcompiled.

vcl.usetest

2000??????

?

?

例:

varnish支持后端多個(gè)虛擬主機(jī):

sub vcl_recv {

???????? if (req.http.host ~ "www.magedu.com" {

???????? }

}

?

例:

強(qiáng)制對(duì)某資源(或后臺(tái)登錄)的請(qǐng)求,不檢查緩存,直接找backend server

sub vcl_recv {

???????? if (req.url ~ "^/test2.html$"{

?????????????????? return (pass);

???????? if (req.url ~ "(?i)^/login" || req.url ~ "(?i)^/admin") {

?????????????????? return (pass);

}

?

例:

對(duì)特定類(lèi)型的資源取消其私有的cookie標(biāo)識(shí),并強(qiáng)行設(shè)定其可以varnish緩存時(shí)長(zhǎng):

sub vcl_babckend_response {

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

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

??????????????????????????? set beresp.ttl = 3600s;

???????? ?????????????????? unset beresp.http.Set-Cookie;

?????????????????? }

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

?????????????????? set beresp.ttl = 600s;

?????????????????? unset beresp.http.Set-Cookie;

???????? }

}

?

?

?

?



一、相關(guān)概念:

http/1.0-->http/1.1(重大改進(jìn):對(duì)緩存功能實(shí)現(xiàn)了更精細(xì)化的設(shè)計(jì))

RFCrequest file comment,每一種協(xié)議都有請(qǐng)求注解文檔,講協(xié)議規(guī)范)

http頁(yè)面由眾多的web object組成,有些是靜態(tài),有些是通過(guò)程序執(zhí)行后生成的;為加速web的訪問(wèn),browser中引入了緩存機(jī)制,能將訪問(wèn)的靜態(tài)內(nèi)容或可緩存的動(dòng)態(tài)內(nèi)容緩存到本地,而后client再次到原始server上請(qǐng)求之前相同的內(nèi)容時(shí),如果原始server上的內(nèi)容沒(méi)發(fā)生改變,就直接使用本地已緩存的數(shù)據(jù),而非從原始server上再次下載,這整個(gè)過(guò)程是如何完成的,http是如何支持緩存機(jī)制的(server上的緩存,并非所有內(nèi)容都能緩存,如登錄時(shí)的賬號(hào)密碼、向用戶返回的cookie,緩存有失效時(shí)間)

?

緩存的類(lèi)型:

public cache(如nginxvarnish

private cache(用戶browser的本地緩存,一般用戶本地的緩存是安全的,但若這個(gè)電腦是公共部門(mén)的,很多人使用,相對(duì)來(lái)說(shuō)也不安全)

?

一般能緩存的前提是原始server上的內(nèi)容沒(méi)發(fā)生改變的,client怎么知道他請(qǐng)求的內(nèi)容在自己本地緩存中有沒(méi)失效,從而不用去原始server上獲取數(shù)據(jù),解決方案:

1)服務(wù)器在第一次響應(yīng)用戶的請(qǐng)求時(shí),在http首部中明確告訴client此資源可以緩存的有效時(shí)長(zhǎng)為10min,使用expires指明過(guò)期時(shí)間,如Expires: Fri , 12 May 2006 18:53:33 GMT

2server將數(shù)據(jù)響應(yīng)給client時(shí)沒(méi)設(shè)置緩存期限,但client覺(jué)得這是個(gè)靜態(tài)內(nèi)容可以緩存(client自己設(shè)置了一些緩存策略,如只要是靜態(tài)內(nèi)容我就緩存),緩存下來(lái)之后并不知道遠(yuǎn)程server中是否改變,當(dāng)再次請(qǐng)求之前請(qǐng)求的內(nèi)容時(shí),告訴server我這存的有一份它的上一次修改時(shí)間是什么時(shí)候,server一對(duì)比發(fā)現(xiàn)同一對(duì)象的修改時(shí)間一致,由此可知server上的內(nèi)容沒(méi)改變,于是serverclient響應(yīng)碼304Not Modified),告訴client此前內(nèi)容沒(méi)改變你可以繼續(xù)使用,于是clientbrowser直接整合本地緩存的資源得以顯示

?

以上是基于時(shí)間來(lái)實(shí)現(xiàn)緩存機(jī)制控制的(http/1.0的緩存機(jī)制是靠prog來(lái)標(biāo)記能否緩存,并使用Expires定義某資源到什么時(shí)候過(guò)期);http/1.1?對(duì)緩存機(jī)制引入了很多首部,有些首部專用于client,有些首部專用于server,讓雙方基于某種功能進(jìn)行協(xié)商,判定緩存對(duì)象是否能進(jìn)一步使用的機(jī)制)

?

緩存相關(guān)的http首部:

1Expires(絕對(duì)時(shí)間計(jì)時(shí)法,絕對(duì)日期時(shí)間,GMT格式,如Expires: Fri , 12 May 2006 18:53:33 GMT,它返回給client的時(shí)間是明確的時(shí)間,clientbrowser緩存了這個(gè)資源后,若再次發(fā)起請(qǐng)求同樣內(nèi)容時(shí),只要在這個(gè)時(shí)間內(nèi)就不去server請(qǐng)求了直接從本地取,Expires的缺陷(若clientserver上的時(shí)間不一致就無(wú)法比較了),這種機(jī)制在http/1.0上常用,而在http/1.1上使用時(shí)長(zhǎng)來(lái)定義max-age

2cache-control中的max-agemax-agehttp/1.1中使用,用于定義時(shí)長(zhǎng),明確告訴client某個(gè)資源可緩存多長(zhǎng)時(shí)間,從server發(fā)送這個(gè)資源開(kāi)始倒計(jì)時(shí),只要倒計(jì)時(shí)結(jié)束,緩存資源立即失效,如Cache-Control:max-age=600

注:如果既指定Expires又在cache-control中指定max-age,那Expires的設(shè)定將被忽略

注:cache-controlhttp中重要的首部,用于定義所有的緩存機(jī)制都必須遵循緩存指示,無(wú)論時(shí)間有無(wú)過(guò)期或有沒(méi)有給最長(zhǎng)緩存時(shí)間都要接受cache-control的控制,就算某個(gè)資源定義可緩存兩天,但同時(shí)又使用了cache-control指令告訴你不能進(jìn)行緩存,那結(jié)果就是不能緩存,指令包括有:publicprivateno-cacheno-storemax-ages-maxagemust-reval-idate

public(放在public cache上,所有人都能獲取,不涉及隱私泄露)

private(只能緩存在用戶的私有緩存區(qū)域,像nginxvarnish這樣的public cache server是不能緩存的)

no-cache(表示可以緩存,但每次都要向server發(fā)起原始資源驗(yàn)證,沒(méi)有標(biāo)記no-cache時(shí)只要在過(guò)期時(shí)間內(nèi),直接從本地獲取不用向server驗(yàn)證這個(gè)資源能否用,而標(biāo)記了no-cache不論在不在過(guò)期時(shí)間內(nèi)都要向server驗(yàn)證)

s-maxage(主要控制私有緩存的過(guò)期期限)

3Etag(響應(yīng)首部,某些站點(diǎn),數(shù)據(jù)變化頻率很高,如client1s里發(fā)起好幾次請(qǐng)求index.html這個(gè)資源(Expires: Fri , 12 May2006 18:53:33 GMT),但在server1s內(nèi)更新了好幾次頁(yè)面(主頁(yè)動(dòng)態(tài)生成),對(duì)于這個(gè)對(duì)象clientserver時(shí)間的比較結(jié)果還是之前的時(shí)間,但實(shí)際server上的資源已經(jīng)改變了,所以時(shí)間戳這種方法過(guò)于粗糙,這種按秒計(jì)時(shí)不足以描述頁(yè)面文件的變化頻率,有可能讓已失效的緩存繼續(xù)使用,因此引入Etagextended tag擴(kuò)展標(biāo)記,給頁(yè)面定義版本號(hào)(版本號(hào)是隨機(jī)生成的,每次生成一個(gè)頁(yè)面都會(huì)自動(dòng)加版本號(hào)),Etag是個(gè)響應(yīng)首部,用于在響應(yīng)報(bào)文中為某web資源定義版本標(biāo)識(shí)符,這樣client過(guò)來(lái)驗(yàn)證不是基于時(shí)間戳而是對(duì)比Etag,就算更新頻率在秒級(jí)以下也能驗(yàn)證資源是否發(fā)生改變)

注:(1)(2)都是絕對(duì)判定法,http/1.1引入條件判斷,每次驗(yàn)證資源時(shí)是向server發(fā)起詢問(wèn)條件,如Last-ModifiedIf-Modified-Since

4Last-Modified(響應(yīng)首部,某資源在server上最后修改的時(shí)間,當(dāng)client第一次請(qǐng)求某資源時(shí),server返回狀態(tài)200,內(nèi)容是client請(qǐng)求的內(nèi)容,同時(shí)有Last-Modified屬性標(biāo)記此文件在server上最后被修改的時(shí)間,如Last-Modified : Fri , 12 May 2006 18:53:33 GMT

5If-Modified-Since(條件式請(qǐng)求首部,當(dāng)client第二次請(qǐng)求相同的內(nèi)容時(shí)詢問(wèn)server此對(duì)象Last-Modified是否發(fā)生了改變,若沒(méi)改變server響應(yīng)給client304Not Modified),若改變了則響應(yīng)改變的內(nèi)容與第一次請(qǐng)求類(lèi)似,從而保證不向client重復(fù)發(fā)出資源,也保證當(dāng)server有變化時(shí)client能得到最新的資源)

6If-None-Match(條件式請(qǐng)求首部,這是個(gè)否定請(qǐng)求,clinet第二次請(qǐng)求相同內(nèi)容時(shí)會(huì)詢問(wèn)server之前發(fā)的某個(gè)資源的Etag是否不匹配,server若回答是則不匹配,響應(yīng)新資源,若server回答否則client使用之前的緩存)

注:If-Modified-SinceLast-Modified有關(guān),If-None-MatchEtag有關(guān),這整個(gè)過(guò)程:

client請(qǐng)求一個(gè)頁(yè)面A

server返回頁(yè)面A,并給A加上Last-ModifiedEtag

client展示頁(yè)面A,并將頁(yè)面和Last-ModifiedEtag一同緩存;

client再次請(qǐng)求頁(yè)面A,將Last-ModifiedEtag一同傳給server(在首部使用If-Modified-SinceIf-None-Match分別詢問(wèn)Last-ModifiedEtag是否修改);

server檢查Last-ModifiedEtag判斷出是否修改,若未修改則響應(yīng)304和一個(gè)空的響應(yīng)體

7Vary(響應(yīng)首部,原始server根據(jù)請(qǐng)求來(lái)源的不同響應(yīng)不同的首部,Vary通知緩存機(jī)制client獲取頁(yè)面是如何得到頁(yè)面的,常用的有:Vary:Accept-Encodingclient若支持壓縮功能在請(qǐng)求時(shí)將請(qǐng)求報(bào)文壓縮,那server在響應(yīng)時(shí)也使用壓縮返回,Vary根據(jù)client的編碼機(jī)制(文本或gzip壓縮或deflate壓縮)server采用相應(yīng)的機(jī)制返回)

8Age(緩存server可發(fā)送一個(gè)額外的響應(yīng)首部,用于指定響應(yīng)的有效期限,browser通常根據(jù)此首部決定內(nèi)容的緩存時(shí)長(zhǎng),如果響應(yīng)報(bào)文首部還使用了max-age指令,那緩存的有效時(shí)長(zhǎng)為max-age減去Age的結(jié)果)

?

假設(shè)我們的reverse proxy上提供緩存,后端是RS(原始server),clientreverse proxy請(qǐng)求某頁(yè)面,reverse proxy中有該頁(yè)面的緩存則直接響應(yīng)給clientclient于是在本地緩存),若reverse proxy中沒(méi)該頁(yè)面的緩存,則reverse proxy向原始server發(fā)起請(qǐng)求,原始server響應(yīng)資源給reverse proxy,同時(shí)一并給一個(gè)首部,如Cache-Control:max-age=600reverse proxy將資源緩存下來(lái)在600s內(nèi)都有效,reverse proxy于是重新構(gòu)建首部并響應(yīng)給clientreverse proxy構(gòu)建首部時(shí)可以自定義告訴client什么時(shí)候過(guò)期,如告訴client可以緩存1年,也可告訴client緩存1min),假設(shè)reverse proxyclient的過(guò)期時(shí)長(zhǎng)是1min,當(dāng)同一client再次請(qǐng)求同樣內(nèi)容時(shí)(若在緩存過(guò)期時(shí)間內(nèi)(1min內(nèi))則從本地緩存中直接取;若過(guò)了過(guò)期時(shí)間(1minclient不會(huì)立即清除緩存,而是使用條件式請(qǐng)求首部請(qǐng)求,reverse proxy比較兩次時(shí)間,若時(shí)間一樣則向client返回304reverse proxy于是再給client一個(gè)緩存過(guò)期時(shí)間(1min),所以就算過(guò)了過(guò)期時(shí)間也不一定從reverse proxy上重復(fù)獲取數(shù)據(jù);若是強(qiáng)制刷新ctrl+F5則仍會(huì)到reverse proxy上請(qǐng)求)

client在第11min時(shí)reverse proxy請(qǐng)求同一頁(yè)面,reverse proxy發(fā)現(xiàn)本地緩存已失效(reverse proxy不會(huì)使用已失效內(nèi)容響應(yīng)的),它向原始server發(fā)起條件式請(qǐng)求(If-Modified-SinceIf-None-Match),若原始server發(fā)現(xiàn)沒(méi)修改則返回304Not Modified),這樣reverse proxy的本地緩存時(shí)間就更新了,于是使用本地緩存響應(yīng)給client

?

舉例:

第一次請(qǐng)求時(shí):

再次刷新后:

?

?

cache server并不是緩存任意數(shù)據(jù)(不允許緩存某些數(shù)據(jù)),如不能緩存用戶的cookie信息,如果用戶請(qǐng)求的內(nèi)容中有變化的cookie信息的話,緩存是命中不了的,緩存中是key:value,若key中包含經(jīng)常變化的內(nèi)容,命中率是很低的,很多時(shí)候緩存時(shí)都把cookie信息去掉,以提高命中率;不能緩存某些動(dòng)態(tài)生成的資源,如表單中填入的賬號(hào)密碼;若請(qǐng)求方法是PUTPOST寫(xiě)操作,也不能緩存,一般緩存的都是GET操作的數(shù)據(jù)(就算是GET操作若包含用戶的認(rèn)證授權(quán)類(lèi)信息也不能緩存)

?

可在cache server上自定義緩存策略(把某些資源根據(jù)我們自己的理解從原始server上剝離出來(lái)自己定義這些資源的緩存時(shí)間),如cache server到原始server上請(qǐng)求數(shù)據(jù),若請(qǐng)求的是站點(diǎn)的LOGO圖片,雖原始server告訴cache server可緩存10min,但cache server(管理者)覺(jué)得該內(nèi)容是靜態(tài)的而且很長(zhǎng)時(shí)間都不會(huì)變,于是cache server響應(yīng)時(shí)告訴client可緩存半年,client在自己本地私有緩存中保存的內(nèi)容越多,那向server發(fā)起請(qǐng)求的或獲取的數(shù)據(jù)就越少,資源發(fā)送少了,帶寬占用率就小了,client從本地緩存直接拿數(shù)據(jù)會(huì)很快,這樣用戶體驗(yàn)度就好

?

?cache server放到離client越近越好(最好放在家門(mén)口),盡量將資源丟到用戶的緩存中,我們電腦上或手機(jī)上使用時(shí)間長(zhǎng)了會(huì)緩存一些數(shù)據(jù),這樣使得上網(wǎng)速度更快并節(jié)省流量,某些軟件會(huì)提示清理垃圾,若清理了下次請(qǐng)求將占用帶寬重新獲取

?

緩存擴(kuò)展結(jié)構(gòu):CDNcache delivery network,內(nèi)容分發(fā)網(wǎng)絡(luò)),如圖:

clientserver這之間可定義N層緩存(n個(gè)cache servercache server之間是分層次的),client請(qǐng)求到cache server11號(hào)發(fā)現(xiàn)自己沒(méi)有要響應(yīng)的內(nèi)容時(shí)它不會(huì)去找原始server,它會(huì)先找它的兄弟服務(wù)器(cache server22若沒(méi)有再去找它的父cache server33沒(méi)有找它的父cache server4,父cache server中沒(méi)有,由父緩存找原始server12是兄弟服務(wù)器(sibling),31的父(parent),43的父),這些cache server之間通過(guò)內(nèi)容緩存協(xié)議且能共享緩存對(duì)象共同組成的網(wǎng)絡(luò)叫CDN,由此client請(qǐng)求時(shí)在中間這個(gè)網(wǎng)絡(luò)上就可取得所有內(nèi)容,同時(shí)這些cache server可定義一些策略,如定期到原始server上獲取數(shù)據(jù)無(wú)論client有無(wú)請(qǐng)求

為使用戶體驗(yàn)好同時(shí)又減輕server壓力使用CDN,如下圖四個(gè)區(qū)域組成的CDN

未用CDN前,DNS解析:www.magedu.com? in?A? 1.1.1.1

使用CDNDNS要解析成別名,指向cache server上的某一個(gè),如指向杭州CDN節(jié)點(diǎn)(www.magedu.com? in?CNAME? hz.cdn.com),這樣杭州用戶訪問(wèn)會(huì)很快,其它區(qū)域的用戶訪問(wèn)還是很慢,用智能DNS解決(根據(jù)client來(lái)源判定它屬于哪個(gè)區(qū)域網(wǎng)絡(luò),于是DNS解析時(shí)不是四個(gè)都返回,而是僅返回離它最近最快的那個(gè)cache server的域名)

智能DNS+CDN這才是真正意義的CDN,當(dāng)client請(qǐng)求時(shí)由該區(qū)域的CDN節(jié)點(diǎn)響應(yīng)內(nèi)容,若該節(jié)點(diǎn)沒(méi)相應(yīng)內(nèi)容,它不去找源站而是找離它近的節(jié)點(diǎn),兄弟服務(wù)器和父服務(wù)器都沒(méi)有才找源站

?

這些cache server能根據(jù)內(nèi)容緩存協(xié)議來(lái)實(shí)現(xiàn)緩存對(duì)象共享,高級(jí)CDN還能實(shí)現(xiàn)內(nèi)容路由(某個(gè)cache server上沒(méi)有內(nèi)容時(shí)自動(dòng)找有內(nèi)容的cache server),使得盡可能不去找原始server,這并不能完全避免找原始server(如動(dòng)態(tài)內(nèi)容),就算緩存的內(nèi)容是靜態(tài)的,也不會(huì)把整站的內(nèi)容都緩存上去,只能緩存一部分,若緩存策略定義的好,將站點(diǎn)的熱區(qū)數(shù)據(jù)都拉到cache server上實(shí)現(xiàn)盡可能多的在cache server上緩存

CDN通常是按流量收費(fèi),視頻站點(diǎn)和圖片站點(diǎn)都要用CDN否則流量大了很容易垮掉

對(duì)于中小型電子商務(wù)站點(diǎn)可自建CDN,前提要使用智能DNS(可自建智能DNS,也可使用公共的智能DNS serverdnspod

注:dnspod在防DDOS方面很強(qiáng),每秒解析達(dá)到數(shù)百萬(wàn),還可達(dá)到秒級(jí)的更新,更新后隨時(shí)生效,還有監(jiān)控原始server的功能,原始server還可通過(guò)它做LB完成health check

DNS本身也要分區(qū)域(如北方電信、南方聯(lián)通等),訪問(wèn)網(wǎng)站不只是獲取網(wǎng)頁(yè)的時(shí)間還有DNS解析返回,再請(qǐng)求資源,若DNS很慢也影響用戶體驗(yàn)

bind dlz+{mysql,pgsql,oracke,DB4}http://bind-dlz.sourceforge.net/,將用戶的資源放到數(shù)據(jù)庫(kù)中會(huì)很慢,如果不是做公共dns server僅為自己公司解析可放在file中,dns啟動(dòng)時(shí)會(huì)直接加載至內(nèi)存中;一般使用bind即可(bind本身就提供了智能解析(view)

注:DB4,基于hash編碼的數(shù)據(jù)庫(kù)

?

varnishhttps://www.varnish-cache.org/):

互聯(lián)網(wǎng)早期的cache serversquid(烏賊,章魚(yú),八爪魚(yú))

varnish本身是reverse proxy server同時(shí)又提供cache功能,配置簡(jiǎn)單、接口簡(jiǎn)單、監(jiān)控接口豐富,由于采用新架構(gòu)設(shè)計(jì),之后擴(kuò)展要比squid容易,功能與nginx近似,但varnish在創(chuàng)建連接、維持連接的能力比nginx差遠(yuǎn)了,通常使用nginx+varnishnginx處理連接,varnish專門(mén)負(fù)責(zé)緩存),也可nginx+squidsquid功能很強(qiáng)大,支持正向代理、反向代理、ACL、支持內(nèi)容分發(fā)協(xié)議,特性非常豐富,配置復(fù)雜)

varnish盡可能利用時(shí)下最新的技術(shù),時(shí)下最好的軟件設(shè)計(jì)結(jié)構(gòu),時(shí)下安全體系的諸多經(jīng)驗(yàn),站在前人的基礎(chǔ)上設(shè)計(jì)的,但squid也寶刀未老,早期淘寶在前端的cache server就使用100多臺(tái)server創(chuàng)建的squid cache cluster,優(yōu)化后的命中率達(dá)到97%(純靜態(tài)內(nèi)容),做到這地步要對(duì)站點(diǎn)的靜態(tài)資源做好篩選(要將哪些內(nèi)容放到cache server上)

squid?VS? varnish(同httpd? VS?nginx

?

?

varnish architecture(與nginx類(lèi)似,是master/slave架構(gòu)):

主進(jìn)程(管理進(jìn)程management,負(fù)責(zé)配置文件分析、裝載新配置文件、啟動(dòng)子進(jìn)程;Management進(jìn)程主要實(shí)現(xiàn)應(yīng)用新的配置(若檢測(cè)到VCL配置文件有語(yǔ)法錯(cuò)誤則拒絕編譯,避免子進(jìn)程加載錯(cuò)誤配置導(dǎo)致緩存崩潰)、編譯VCL、監(jiān)控varnish、初始化varnish以及提供一個(gè)命令行接口等。Management進(jìn)程會(huì)每隔幾秒鐘探測(cè)一下Child進(jìn)程以判斷其是否正常運(yùn)行,如果在指定的時(shí)長(zhǎng)內(nèi)未得到Child進(jìn)程的回應(yīng),Management將會(huì)重啟此Child進(jìn)程):

CLI interface(通過(guò)命令行接口與命令行的控制指令進(jìn)行交互)

telnet interface(為安全這種方式已很少用,可用專用的client工具varnishadm連到管理進(jìn)程完成啟動(dòng)停止等)

web interfaceGUI接口)

?

子進(jìn)程(child|cache進(jìn)程,child提供服務(wù)、發(fā)送至后端并響應(yīng)用戶請(qǐng)求;cache緩存管理的進(jìn)程,緩存清理、緩存有效期限檢查等):

command line

storage/hashing(存儲(chǔ)緩存,用key定義查找標(biāo)準(zhǔn),將key放在某個(gè)backet中實(shí)現(xiàn)O(1)的查找,查找到的內(nèi)容即是value

log/statsvarnish的日志不是保存在file中,有磁盤(pán)IO,而是在內(nèi)存中,啟動(dòng)服務(wù)時(shí)就明確說(shuō)明用多大空間保存日志,空間占完后將覆蓋之前的文件繼續(xù)使用,一圈圈輪著使用,日志記錄有client的請(qǐng)求數(shù)、client請(qǐng)求命中數(shù)、沒(méi)命中數(shù)、server運(yùn)行多長(zhǎng)時(shí)間等;可用工具將日志導(dǎo)出查看,如varnishlog等)

accept(接收用戶請(qǐng)求并將請(qǐng)求轉(zhuǎn)至workerthreads上)

backend communication(后端主機(jī)通信)

worker threads(一個(gè)線程響應(yīng)多個(gè)請(qǐng)求,child進(jìn)程會(huì)為每個(gè)會(huì)話啟動(dòng)一個(gè)worker線程,因此,在高并發(fā)的場(chǎng)景中可能會(huì)出現(xiàn)數(shù)百個(gè)worker線程甚至更多)

object expiry(從緩存中清理過(guò)期內(nèi)容)

?

varnish的主進(jìn)程management只有一個(gè),child進(jìn)程由多個(gè)不同的線程組成,varnish總體連接數(shù)在大于5000時(shí)性能會(huì)下降,一般不會(huì)讓工作線程接受太多連接,性能有上限,假設(shè)有10個(gè)varnish server每個(gè)平均接受5000個(gè)連接,那10個(gè)就能接受5W個(gè)了,前端nignx已處理一些請(qǐng)求再將多個(gè)請(qǐng)求轉(zhuǎn)到varnish server上,這種架構(gòu)已達(dá)到億級(jí)或十億級(jí)PV

?

VCLvarnish configuration language),底層用C開(kāi)發(fā),完全兼容C語(yǔ)言,提供編程接口,要寫(xiě)程序提供配置文件,用VCL開(kāi)發(fā)程序時(shí)指明varnish怎么工作(哪些內(nèi)容緩存、哪些內(nèi)容不緩存、哪些內(nèi)容不通過(guò)緩存來(lái)取等),為使VCL開(kāi)發(fā)出的程序更加高效,要將其編譯為二進(jìn)制格式(使用VCL編寫(xiě)好配置文件后,使用gcc編譯)

配置文件編譯完后生成共享模塊,child/cache如何工作就取決于共享模塊中的定義,二進(jìn)制格式的配置文件被子進(jìn)程child/cache讀取,child從后端server取得內(nèi)容后要緩存在本地,由storage/hashing子模塊將緩存內(nèi)容存下來(lái)

?

VCL工作在varnish的狀態(tài)引擎state engine上,在varnish內(nèi)部有多個(gè)state engine(同iptablesnetfilter框架中的幾個(gè)接口類(lèi)似(勾子函數(shù)),若某個(gè)報(bào)文不經(jīng)過(guò)這幾個(gè)勾子函數(shù)將檢測(cè)不到,所以這幾個(gè)勾子要放在報(bào)文必經(jīng)的路口,使得報(bào)文必須要經(jīng)過(guò)這其中1個(gè)或幾個(gè)勾子,在這些勾子上就能實(shí)現(xiàn)管理)

如圖:橢圓表示state engine(又叫domain),菱形表示檢查機(jī)制(條件判斷)

vcl_recv(第一個(gè)入口的state engine,請(qǐng)求報(bào)文接進(jìn)來(lái))

vcl_recv-->vcl_pass(例如是動(dòng)態(tài)內(nèi)容或用戶的私有內(nèi)容直接到后端去取)

vcl_recv-->vcl_hash(根據(jù)key來(lái)查找本地緩存)

vcl_recv-->vcl_pipe(不對(duì)client進(jìn)行檢查或做出任何操作,而是在client和后端server之間建立專用pipe,并直接將數(shù)據(jù)在二者之間傳送;keep-alive連接中后續(xù)傳送的數(shù)據(jù)也都通過(guò)此管道進(jìn)行直接傳送,并不會(huì)出現(xiàn)在任何日志中)

vcl_hit-->vcl_deliver(命中后交給vcl_deliver再投遞給client

vcl_hit-->vcl_pass(在管理的CLI下,命中后將緩存清除)

vcl_pass(可對(duì)三個(gè)state enginedomain)過(guò)來(lái)的報(bào)文統(tǒng)一處理(vcl_recvvcl_hitvcl_miss),統(tǒng)一到一個(gè)反向操作上(例如命中后不去找緩存而是找vcl_fetch繼而找后端server))

vcl_fetch(到這個(gè)domain上就要聯(lián)系后端server,這個(gè)域上會(huì)定義一些語(yǔ)句來(lái)判定哪些內(nèi)容緩存哪些不緩存(如authcookie有關(guān)的字串就不緩存))

路線:

vcl_recv-->vcl_hash-->vcl_hit-->vcl_deliver

vcl_recv-->vcl_hash-->vcl_miss-->vcl_fetch-->vcl_deliver

vcl_recv-->vcl_pass-->vcl_fetch-->vcl_vcl_deliver

?

每個(gè)state engine中定義一堆條件判斷(如定義vcl_recv在什么情況下去找vcl_hash,在什么情況下找vcl_pass,例如某些client不允許訪問(wèn)、某些client查找哪些資源、哪些資源不允許緩存等,通過(guò)定義各種條件判斷指揮著到下一個(gè)數(shù)據(jù)流或state engine

每個(gè)state engine又被叫作domain,每個(gè)domain都有可執(zhí)行的指令(如netfilter上各種鏈上的規(guī)則,每個(gè)鏈所接受的規(guī)則是不一樣的,處理完成有可能還要經(jīng)過(guò)下個(gè)鏈,有可能直接返回),而對(duì)varnish的每個(gè)state engine都要走向下一步(除vcl_deliver

VCL編程,所寫(xiě)的代碼,只對(duì)當(dāng)前state engine生效(可理解為函數(shù),函數(shù)執(zhí)行完有返回值),返回的是什么就決定下一步怎么走,若return返回hash就找vcl_hash,若return pass則找vcl_pass,到底返回哪個(gè)要做寫(xiě)一大堆的if語(yǔ)句做出判斷

以上涉及到編程,程序中策略寫(xiě)的好,緩存命中率就高

?

VCL語(yǔ)法:

1)注釋:///*(單選注釋);*/(多行注釋)

2sub $name(定義函數(shù),subroutine子例程)

3)不支持循環(huán),有內(nèi)置變量(內(nèi)置變量應(yīng)用位置獨(dú)特,有的變量應(yīng)用在前半段(請(qǐng)求報(bào)文首部),有的變量應(yīng)用在后半段(響應(yīng)報(bào)文首部))

4)使用終止語(yǔ)句,沒(méi)有返回值

5)域?qū)S?#xff08;每個(gè)state engine定義自己的程序)

6)操作符(=賦值、==等值比較、~模式匹配、!&&||

VCL的函數(shù)不接受參數(shù)且沒(méi)有返回值,因此并非真正意義的函數(shù),這也限定了VCL內(nèi)部的數(shù)據(jù)傳遞只能隱藏在http首部?jī)?nèi)部進(jìn)行,VCLreturn語(yǔ)句用于將控制權(quán)從VCL狀態(tài)引擎返回給varnish,而非默認(rèn)函數(shù),這就是VCL只有終止語(yǔ)句沒(méi)有返回值的原因;同時(shí)對(duì)于每個(gè)域來(lái)說(shuō),可定義一個(gè)或多個(gè)終止語(yǔ)句,告訴varnish下一步采取何種操作(如查詢緩存或不查詢緩存等)

?

VCL的內(nèi)置函數(shù):

regsub(str,regex,sub)

regsuball(str,regex,sub)

以上兩項(xiàng)實(shí)現(xiàn)替換(substituend,用于將regexp匹配到的str替換為sub,相當(dāng)于nginxrewrite,而regsuball相當(dāng)于加了修飾符/g的替換)

ban(expression)

ban_url(regex)

purge

以上三項(xiàng)實(shí)現(xiàn)緩存清理,給某個(gè)緩存對(duì)象設(shè)置柵欄,阻止對(duì)其使用,先放到禁止列表中再禁止使用,purge僅允許有權(quán)限經(jīng)過(guò)認(rèn)證的管理員使用

hash_data(str)(取得一個(gè)字符串的hash值,若這個(gè)字符串是緩存中的某個(gè)key,則可判定緩存中是否有)

return()(當(dāng)某個(gè)域運(yùn)行結(jié)束時(shí)將控制權(quán)返回給varnish,并指示下一步的動(dòng)作,可以返回的指令有:lookup,pass,pipe,hit_for_pass,fetch,deliver,hash等),特定域只能返回特定的指令)

return(restart)(重新運(yùn)行整個(gè)VCL,即從vcl_recv開(kāi)始進(jìn)行處理,每一次重啟都會(huì)增加req.restarts變量中的值,而max_restarts參數(shù)則用于限定最大重啟次數(shù),例如vcl_recv-->vcl_hash-->vcl_miss-->vcl_pass-->restart-->vcl_recv……,未命中可不讓去vcl_fetch,讓重啟,在vcl_pass中寫(xiě)入regsub(……)url重寫(xiě)rewrite,再在vcl_recv上跑一遍,有可能就命中了,若寫(xiě)了錯(cuò)誤的rewrite將導(dǎo)致死循環(huán),restart判定若超過(guò)5次就退出直接向client返回error

注:vcl_deliver要能在client請(qǐng)求內(nèi)容不存在時(shí)或restart超過(guò)5次退出時(shí),返回錯(cuò)誤頁(yè)面,varnish-server要能生成錯(cuò)誤響應(yīng)頁(yè)(如404,502等)

?

?

?

?

?

以上是學(xué)習(xí)《馬哥運(yùn)維課程》做的筆記。


轉(zhuǎn)載于:https://blog.51cto.com/jowin/1739282

總結(jié)

以上是生活随笔為你收集整理的Linux运维 第三阶段 (十八) varnish的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。