Web Page Cache: 程åºçš„è¿è¡Œå…·æœ‰å±€éƒ¨æ€§ç‰¹å¾ï¼š 时间局部性 空间局部性 cacheï¼šå‘½ä¸ çƒåŒºï¼šå±€éƒ¨æ€§ï¼› 时效性: 缓å˜ç©ºé—´è€—尽:LRU è¿‡æœŸï¼šç¼“å˜æ¸…ç† ç¼“å˜å‘½ä¸çŽ‡ï¼šhit/(hit+miss) (0,1) 页é¢å‘½ä¸çŽ‡ï¼šåŸºäºŽé¡µé¢æ•°é‡è¿›è¡Œè¡¡é‡ å—节命ä¸çŽ‡ï¼šåŸºäºŽé¡µé¢çš„ä½“ç§¯è¿›è¡Œè¡¡é‡ ç¼“å˜ä¸Žå¦ï¼š ç§æœ‰æ•°æ®ï¼šprivate,private cacheï¼› 公共数æ®ï¼špublic, public or private cache; Cache-related Headers Fields The most important caching header fields are: Expires:过期时间; Expires:Thu, 22 Oct 2026 06:34:30 GMT Cache-Control Etag Last-Modified If-Modified-Since If-None-Match Vary Age ç¼“å˜æœ‰æ•ˆæ€§åˆ¤æ–机制: 过期时间:Expires HTTP/1.0 Expires HTTP/1.1 Cache-Control: maxage= Cache-Control: s-maxage= æ¡ä»¶å¼è¯·æ±‚: Last-Modified/If-Modified-Since Etag/If-None-Match Expires:Thu, 13 Aug 2026 02:05:12 GMT Cache-Control:max-age=315360000 ETag:"1ec5-502264e2ae4c0" Last-Modified:Wed, 03 Sep 2014 10:00:27 GMT cache-request-directive = "no-cache" | "no-store" | "max-age" "=" delta-seconds | "max-stale" [ "=" delta-seconds ] | "min-fresh" "=" delta-seconds | "no-transform" | "only-if-cached" | cache-extension cache-response-directive = "public" | "private" [ "=" <"> 1#field-name <"> ] | "no-cache" [ "=" <"> 1#field-name <"> ] | "no-store" | "no-transform" | "must-revalidate" | "proxy-revalidate" | "max-age" "=" delta-seconds | "s-maxage" "=" delta-seconds | cache-extension å¼€æºè§£å†³æ–¹æ¡ˆï¼š squid: varnish: varnish官方站点: http://www.varnish-cache.org/ Community Enterprise This is Varnish Cache, a high-performance HTTP accelerator. ç¨‹åºæž¶æž„: Manager进程 Cacher进程,包å«å¤šç§ç±»åž‹çš„线程: accept, worker, expiry, ... shared memory log: 统计数æ®ï¼šè®¡æ•°å™¨ï¼› 日志区域:日志记录; varnishlog, varnishncsa, varnishstat... é…置接å£ï¼šVCL Varnish Configuration Language, vcl complier --> c complier --> shared object varnish的程åºçŽ¯å¢ƒï¼š /etc/varnish/varnish.params: é…ç½®varnishæœåŠ¡è¿›ç¨‹çš„å·¥ä½œç‰¹æ€§ï¼Œä¾‹å¦‚ç›‘å¬çš„地å€å’Œç«¯å£ï¼Œç¼“å˜æœºåˆ¶ï¼› /etc/varnish/default.vcl:é…ç½®å„Child/Cache线程的工作属性; 主程åºï¼š /usr/sbin/varnishd CLI interface: /usr/bin/varnishadm Shared Memory Log交互工具: /usr/bin/varnishhist /usr/bin/varnishlog /usr/bin/varnishncsa /usr/bin/varnishstat /usr/bin/varnishtop 测试工具程åºï¼š /usr/bin/varnishtest VCLé…置文件é‡è½½ç¨‹åºï¼š /usr/sbin/varnish_reload_vcl Systemd Unit File: /usr/lib/systemd/system/varnish.service varnishæœåŠ¡ /usr/lib/systemd/system/varnishlog.service /usr/lib/systemd/system/varnishncsa.service 日志æŒä¹…çš„æœåŠ¡ï¼› varnish的缓å˜å˜å‚¨æœºåˆ¶( Storage Types): · malloc[,size] 内å˜å˜å‚¨ï¼Œ[,size]用于定义空间大å°ï¼›é‡å¯åŽæ‰€æœ‰ç¼“å˜é¡¹å¤±æ•ˆï¼› · file[,path[,size[,granularity]]] 文件å˜å‚¨ï¼Œé»‘ç›’ï¼›é‡å¯åŽæ‰€æœ‰ç¼“å˜é¡¹å¤±æ•ˆï¼› · persistent,path,size 文件å˜å‚¨ï¼Œé»‘ç›’ï¼›é‡å¯åŽæ‰€æœ‰ç¼“å˜é¡¹æœ‰æ•ˆï¼›å®žéªŒï¼› varnish程åºçš„选项: 程åºé€‰é¡¹ï¼š/etc/varnish/varnish.params文件 -a address[:port][,address[:port][...],默认为6081端å£ï¼› -T address[:port],默认为6082端å£ï¼› -s [name=]type[,options],定义缓å˜å˜å‚¨æœºåˆ¶ï¼› -u user -g group -f config:VCLé…置文件; -F:è¿è¡ŒäºŽå‰å°ï¼› ... è¿è¡Œæ—¶å‚数:/etc/varnish/varnish.params文件, DEAMON_OPTS DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" -p param=value:设定è¿è¡Œå‚æ•°åŠå…¶å€¼ï¼› å¯é‡å¤ä½¿ç”¨å¤šæ¬¡ï¼› -r param[,param...]: è®¾å®šæŒ‡å®šçš„å‚æ•°ä¸ºåªè¯»çжæ€ï¼› é‡è½½vclé…置文件: ~ ]# varnish_reload_vcl varnishadm -S /etc/varnish/secret -T [ADDRESS:]PORT help [<command>] ping [<timestamp>] auth <response> quit banner status start stop vcl.load <configname> <filename> vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> vcl.discard <configname> vcl.list param.show [-l] [<param>] param.set <param> <value> panic.show panic.clear storage.list vcl.show [-v] <configname> backend.list [<backend_expression>] backend.set_health <backend_expression> <state> ban <field> <operator> <arg> [&& <field> <oper> <arg>]... ban.list é…置文件相关: vcl.list vcl.loadï¼šè£…è½½ï¼ŒåŠ è½½å¹¶ç¼–è¯‘ï¼› vcl.use:激活; vcl.discardï¼šåˆ é™¤ï¼› vcl.show [-v] <configname>:查看指定的é…置文件的详细信æ¯ï¼› è¿è¡Œæ—¶å‚数: param.show -l:显示列表; param.show <PARAM> param.set <PARAM> <VALUE> 缓å˜å˜å‚¨ï¼š storage.list åŽç«¯æœåŠ¡å™¨ï¼š backend.list VCL: â€åŸŸâ€œä¸“有类型的é…ç½®è¯è¨€ï¼› state engine:状æ€å¼•擎; VCL有多个状æ€å¼•擎,状æ€ä¹‹é—´å˜åœ¨ç›¸å…³æ€§ï¼Œä½†å½¼æ¤é—´äº’相隔离;æ¯ä¸ªçжæ€å¼•擎å¯ä½¿ç”¨return(x)指明关è”至哪个下一级引擎; vcl_hash --> return(hit) --> vcl_hit è¯·æ±‚å¤„ç†æµç¨‹ï¼š (1) 接收请求:vcl_recv;判æ–其是å¦å¯ç¼“å˜ï¼› (a) å¯ç¼“å˜ï¼švcl_hash (i) 命ä¸ï¼švcl_hit (ii)未命ä¸ï¼švcl_miss --> vcl_fetch (b) ä¸å¯ç¼“å˜ï¼švcl_fetch (2) å“应:vcl_deliver 回顾: Web Cache: httpå议与缓å˜ç›¸å…³çš„首部 Expires If-Modified-Since/Last-Modified If-None-Match/Etag Cache-Control: 请求报文: å“应报文: no-store, no-cache, max-age, s-maxage, public, private, ... ç¼“å˜æŽ§åˆ¶ï¼š 过期机制:Expires æ¡ä»¶å¼è¯·æ±‚: Varnish:A high-performance HTTP accelerator. v2, v3, v4, v5 v4.0, v4.1 é…置环境: /etc/varnish/varnish.params (/etc/sysconfig/varnishd) 程åºé€‰é¡¹ è¿è¡Œæ—¶å‚æ•° /etc/varnish/default.vcl varnish_reload_vcl命令 varnishadm vcl:é…ç½®è¯è¨€ï¼› VARNISH(2) state engine:状æ€å¼•æ“Žåˆ‡æ¢æœºåˆ¶ request: vcl_recv response: vcl_deliver (1) vcl_hash -(hit)-> vcl_hit --> vcl_deliver (2) vcl_hash -(miss)-> vcl_miss --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver (3) vcl_hash -(purge)-> vcl_purge --> vcl_synth (4) vcl_hash -(pipe)-> vcl_pipe 两个特殊的引擎: vcl_init:在处ç†ä»»ä½•请求之å‰è¦æ‰§è¡Œçš„vcl代ç :主è¦ç”¨äºŽåˆå§‹åŒ–VMODsï¼› vcl_fini:所有的请求都已ç»ç»“æŸï¼Œåœ¨vclé…置被丢弃时调用;主è¦ç”¨äºŽæ¸…ç†VMODsï¼› vclçš„è¯æ³•æ ¼å¼ï¼š (1) VCL files start with vcl 4.0; (2) //, # and /* foo */ for comments; (3) Subroutines are declared with the sub keyword; 例如sub vcl_recv { ...}ï¼› (4) No loops, state-limited variables(å—é™äºŽå¼•擎的内建å˜é‡ï¼‰ï¼› (5) Terminating statements with a keyword for next action as argument of the return() function, i.e.: return(action)ï¼› (6) Domain-specific; The VCL Finite State Machine (1) Each request is processed separately; (2) Each request is independent from others at any given time; (3) States are related, but isolated; (4) return(action); exits one state and instructs Varnish to proceed to the next state; (5) Built-in VCL code is always present and appended below your own VCL; 三类主è¦è¯æ³•: sub subroutine { ... } if CONDITION { ... } else { ... } return(), hash_data() VCL Built-in Functions and Keywords 函数: regsub(str, regex, sub) regsuball(str, regex, sub) ban(boolean expression) hash_data(input) synthetic(str) Keywords: call subroutine, return(action),new,set,unset æ“作符: ==, !=, ~, >, >=, <, <= 逻辑æ“作符:&&, ||, ! å˜é‡èµ‹å€¼ï¼š= 举例:obj.hits if (obj.hits>0) { set resp.http.X-Cache = "HIT via " + server.ip; } else { set resp.http.X-Cache = "MISS via " + server.ip; } å˜é‡ç±»åž‹ï¼š 内建å˜é‡ï¼š req.*:requestï¼Œè¡¨ç¤ºç”±å®¢æˆ·ç«¯å‘æ¥çš„请求报文相关; req.http.* req.http.User-Agent, req.http.Referer, ... bereq.*:由varnishå‘å¾€BE主机的httpd请求相关; bereq.http.* beresp.*:由BE主机å“应给varnishçš„å“应报文相关; beresp.http.* resp.*:由varnishå“应给client相关; obj.*:å˜å‚¨åœ¨ç¼“å˜ç©ºé—´ä¸çš„缓å˜å¯¹è±¡çš„属性;åªè¯»ï¼› 常用å˜é‡ï¼š bereq.*, req.*: bereq.http.HEADERS bereq.request:请求方法; bereq.url:请求的urlï¼› bereq.proto:请求的å议版本; bereq.backend:指明è¦è°ƒç”¨çš„åŽç«¯ä¸»æœºï¼› req.http.Cookie:客户端的请求报文ä¸Cookie首部的值; req.http.User-Agent ~ "chrome" beresp.*, resp.*: beresp.http.HEADERS beresp.status:å“应的状æ€ç ï¼› reresp.proto:å议版本; beresp.backend.name:BE主机的主机åï¼› beresp.ttl:BE主机å“应的内容的余下的å¯ç¼“å˜æ—¶é•¿ï¼› obj.* obj.hits:æ¤å¯¹è±¡ä»Žç¼“å˜ä¸å‘½ä¸çš„æ¬¡æ•°ï¼› obj.ttl:对象的ttl值 server.* server.ip server.hostname client.* client.ip 用户自定义: set unset 示例1:强制对æŸç±»èµ„æºçš„è¯·æ±‚ä¸æ£€æŸ¥ç¼“å˜ï¼š vcl_recv { if (req.url ~ "(?i)^/(login|admin)") { return(pass); } } 示例2:对于特定类型的资æºï¼Œä¾‹å¦‚公开的图片ç‰ï¼Œå–æ¶ˆå…¶ç§æœ‰æ ‡è¯†ï¼Œå¹¶å¼ºè¡Œè®¾å®šå…¶å¯ä»¥ç”±varnish缓å˜çš„æ—¶é•¿ï¼› 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; } } 缓å˜å¯¹è±¡çš„修剪:purge, ban (1) 能执行purgeæ“作 sub vcl_purge { return (synth(200,"Purged")); } (2) 何时执行purgeæ“作 sub vcl_recv { if (req.method == "PURGE") { return(purge); } ... } æ·»åŠ æ¤ç±»è¯·æ±‚的访问控制法则: acl purgers { "127.0.0.0"/8; "10.1.0.0"/16; } sub vcl_recv { if (req.method == "PURGE") { if (!client.ip ~ purgers) { return(synth(405,"Purging not allowed for " + client.ip)); } return(purge); } ... } 如何设定使用多个åŽç«¯ä¸»æœºï¼š backend default { .host = "172.16.100.6"; .port = "80"; } backend appsrv { .host = "172.16.100.7"; .port = "80"; } sub vcl_recv { if (req.url ~ "(?i)\.php$") { set req.backend_hint = appsrv; } else { set req.backend_hint = default; } ... } Director: varnish moduleï¼› 使用å‰éœ€è¦å¯¼å…¥ï¼š import directorï¼› 示例: import directors; # load the directors backend server1 { .host = .port = } backend server2 { .host = .port = } sub vcl_init { new GROUP_NAME = directors.round_robin(); GROUP_NAME.add_backend(server1); GROUP_NAME.add_backend(server2); } sub vcl_recv { # send all traffic to the bar director: set req.backend_hint = GROUP_NAME.backend(); } BE Health Check: backend BE_NAME { .host = .port = .probe = { .url= .timeout= .interval= .window= .threshhold= } } .probe:定义å¥åº·çŠ¶æ€æ£€æµ‹æ–¹æ³•ï¼› .url:检测时请求的URL,默认为â€/"; .request:å‘出的具体请求; .request = "GET /.healthtest.html HTTP/1.1" "Host: www.magedu.com" "Connection: close" .window:基于最近的多少次检查æ¥åˆ¤æ–å…¶å¥åº·çжæ€ï¼› .threshhold:最近.windowä¸å®šä¹‰çš„这么次检查ä¸è‡³æœ‰.threshhold定义的次数是æˆåŠŸçš„ï¼› .interval:检测频度; .timeout:超时时长; .expected_response:期望的å“应ç ,默认为200ï¼› å¥åº·çŠ¶æ€æ£€æµ‹çš„é…置方å¼ï¼š (1) probe PB_NAME = { } backend NAME = { .probe = PB_NAME; ... } (2) backend NAME { .probe = { ... } } 示例: probe check { .url = "/.healthcheck.html"; .window = 5; .threshold = 4; .interval = 2s; .timeout = 1s; } backend default { .host = "10.1.0.68"; .port = "80"; .probe = check; } backend appsrv { .host = "10.1.0.69"; .port = "80"; .probe = check; } varnishçš„è¿è¡Œæ—¶å‚数: 线程模型: cache-worker cache-main ban lurker acceptor: epoll/kqueue: ... çº¿ç¨‹ç›¸å…³çš„å‚æ•°ï¼š åœ¨çº¿ç¨‹æ± å†…éƒ¨ï¼Œå…¶æ¯ä¸€ä¸ªè¯·æ±‚由一个线程æ¥å¤„ç†ï¼› å…¶worker线程的最大数决定了varnish的并å‘å“应能力; thread_pools:Number of worker thread pools. 最好å°äºŽæˆ–ç‰äºŽCPUæ ¸å¿ƒæ•°é‡ï¼› thread_pool_max:The maximum number of worker threads in each pool. thread_pool_min:The minimum number of worker threads in each pool. é¢å¤–æ„义为“最大空闲线程数â€ï¼› 最大并å‘连接数=thread_pools * thread_pool_max thread_pool_timeout:Thread idle threshold. Threads in excess of thread_pool_min, which have been idle for at least this long, will be destroyed. thread_pool_add_delay:Wait at least this long after creating a thread. thread_pool_destroy_delay:Wait this long after destroying a thread. 设置方å¼ï¼š vcl.param 永久有效的方法: varnish.params DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE" varnish日志区域: shared memory log 计数器 æ—¥å¿—ä¿¡æ¯ 1ã€varnishstat - Varnish Cache statistics -1 -1 -f FILED_NAME -l:å¯ç”¨äºŽ-fé€‰é¡¹æŒ‡å®šçš„å—æ®µå称列表; MAIN.cache_hit MAIN.cache_miss # varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss 2ã€varnishtop - Varnish log entry ranking -1 Instead of a continously updated display, print the statistics once and exit. -i taglist,å¯ä»¥åŒæ—¶ä½¿ç”¨å¤šä¸ª-i选项,也å¯ä»¥ä¸€ä¸ªé€‰é¡¹è·Ÿä¸Šå¤šä¸ªæ ‡ç¾ï¼› -I <[taglist:]regex> -x taglist:排除列表 -X <[taglist:]regex> 3ã€varnishlog - Display Varnish logs 4〠varnishncsa - Display Varnish logs in Apache / NCSA combined log format 内建函数: hash_data():指明哈希计算的数æ®ï¼›å‡å°‘差异,以æå‡å‘½ä¸çŽ‡ï¼› regsub(str,regex,sub):把strä¸è¢«regex第一次匹é…到å—符串替æ¢ä¸ºsub;主è¦ç”¨äºŽURL Rewrite regsuball(str,regex,sub):把strä¸è¢«regexæ¯ä¸€æ¬¡åŒ¹é…到å—ç¬¦ä¸²å‡æ›¿æ¢ä¸ºsubï¼› return(): ban(expression) ban_url(regex):Bans所有的其URLå¯ä»¥è¢«æ¤å¤„çš„regex匹é…到的缓å˜å¯¹è±¡ï¼› synth(status,"STRING"):purgeæ“作; 总结: varnish: state engine, vcl varnish 4.0: vcl_init vcl_recv vcl_hash vcl_hit vcl_pass vcl_miss vcl_pipe vcl_waiting vcl_purge vcl_deliver vcl_synth vcl_fini vcl_backend_fetch vcl_backend_response vcl_backend_error sub VCL_STATE_ENGINE backend BE_NAME {} probe PB_NAME {} acl ACL_NAME {} åšå®¢ä½œä¸šï¼šä»¥ä¸Šæ‰€æœ‰å†…容;