SlideShare une entreprise Scribd logo
1  sur  38
Télécharger pour lire hors ligne
r.v. var·nished, var·nish·ing, var·nish·es 
1. To cover with varnish. 
2. To give a smooth and glossy finish to. 
3. To give a deceptively attractive appearance to; gloss over. 
by jnerin 1
Server (cubietruck) 
● AllWinnerTech SOC 
A20 
○ ARM® Cortex™-A7 
Dual-Core 
● 2GB ram 
● SAMSUNG SpinPoint 
F2 EG 1.5TB sata 
hard disk 
● 1Gb Ethernet 
2
Server (cubietruck) 
● Apache 2.2.27-r4 
○ KeepAlive On 
○ MaxKeepAliveRequests 100 
○ KeepAliveTimeout 15 
○ mpm worker: 
StartServers 2 
MinSpareThreads 25 
MaxSpareThreads 75 
ThreadsPerChild 25 
MaxClients 150 
MaxRequestsPerChild 10000 
● PHP 5.5.16 (opcache enabled by default 
64M) 
● mariadb 10.0.14 
(have_query_cache=YES but 
query_cache_size=0) 
3
Test.sh 
#!/bin/bash 
URL="$1" 
LOG="$URL.$(date +%Y%m%d-%H%M%S).log" 
HOST="test" 
IP="192.168.2.3:8080" 
REQUESTS=10000 
CONCURRENCY=20 
exec 6<&1 # Save STDOUT FD 
exec >$LOG 
echo "- Simple test, no concurrency" 
/usr/sbin/ab2 -n $REQUESTS -H "Host: $HOST" http://$IP/$URL 
echo "- Simple test, concurrency" 
/usr/sbin/ab2 -n $REQUESTS -c $CONCURRENCY -H "Host: $HOST" http://$IP/$URL 
echo "- Concurrency & KeepAlive" 
/usr/sbin/ab2 -k -n $REQUESTS -c $CONCURRENCY -H "Host: $HOST" http://$IP/$URL 
echo "- Simple test, no concurrency (Accept-Encoding: gzip)" 
/usr/sbin/ab2 -n $REQUESTS -H "Accept-encoding: gzip" -H "Host: $HOST" http://$IP/$URL 
echo "- Simple test, concurrency (Accept-Encoding: gzip)" 
/usr/sbin/ab2 -n $REQUESTS -c $CONCURRENCY -H "Accept-encoding: gzip" -H "Host: $HOST" http: 
//$IP/$URL 
echo "- Concurrency & KeepAlive (Accept-Encoding: gzip)" 
/usr/sbin/ab2 -k -n $REQUESTS -c $CONCURRENCY -H "Accept-encoding: gzip" -H "Host: $HOST" http: 
//$IP/$URL 
exec 1<&6 6<&- # Restore STDOUT FD 
egrep "^(-|Requests per second)" $LOG 
4
Test1.html 
<html> 
<head> 
<title>Test 1</title> 
</head> 
<body> 
<p>Test 1</p> 
</body> 
</html> 
Simple test, no concurrency 
222.56 req/s 
Simple test, concurrency 
197.06 req/s 
Concurrency & KeepAlive 
679.81 req/s 
Simple test, no concurrency 
(Accept-Encoding: gzip) 
232.75 req/s 
Simple test, concurrency 
(Accept-Encoding: gzip) 
415.48 req/s 
Concurrency & KeepAlive 
(Accept-Encoding: gzip) 
825.26 req/s 
5
Test2.php 
<html> 
<head> 
<title>Test 2</title> 
</head> 
<body> 
<p> 
<?php 
require_once('defaults.php'); 
$link = mysqli_connect($mysql_server, 
$mysql_user, 
$mysql_password,$mysql_database) or die 
("Error " . mysqli_error($link)); 
if ($result = mysqli_query($link, "SELECT 
temperature FROM oregon_data ORDER BY 
receiver_timestamp DESC LIMIT 1")) { 
echo mysqli_fetch_row($result)[0]; 
mysqli_free_result($result); 
} 
mysqli_close($link); 
?> 
</p> 
</body> 
</html> 
Simple test, no concurrency 
120.61 req/s 
Simple test, concurrency 
236.65 req/s 
Concurrency & KeepAlive 
271.19 req/s 
Simple test, no concurrency 
(Accept-Encoding: gzip) 
94.80 req/s 
Simple test, concurrency 
(Accept-Encoding: gzip) 
108.93 req/s 
Concurrency & KeepAlive 
(Accept-Encoding: gzip) 
163.97 req/s 
6
MySQL Query Cache (Qcache) 
mysql -e 'show global variables like "%query_cache%";show status like "Qcache%"' 
+------------------------------+----------+ 
| Variable_name | Value | 
+------------------------------+----------+ 
| have_query_cache | YES | 
| query_cache_limit | 1048576 | 
| query_cache_min_res_unit | 4096 | 
| query_cache_size | 33554432 | 
| query_cache_strip_comments | OFF | 
| query_cache_type | ON | 
| query_cache_wlock_invalidate | OFF | 
+------------------------------+----------+ 
+-------------------------+----------+ 
| Variable_name | Value | 
+-------------------------+----------+ 
| Qcache_free_blocks | 1 | 
| Qcache_free_memory | 33544000 | 
| Qcache_hits | 60030 | 
| Qcache_inserts | 10 | 
| Qcache_lowmem_prunes | 0 | 
| Qcache_not_cached | 97 | 
| Qcache_queries_in_cache | 1 | 
| Qcache_total_blocks | 4 | 
+-------------------------+----------+ 
7
Test2.php + QCache 
<html> 
<head> 
<title>Test 2</title> 
</head> 
<body> 
<p> 
<?php 
require_once('defaults.php'); 
$link = mysqli_connect($mysql_server, 
$mysql_user, 
$mysql_password,$mysql_database) or die 
("Error " . mysqli_error($link)); 
if ($result = mysqli_query($link, "SELECT 
temperature FROM oregon_data ORDER BY 
receiver_timestamp DESC LIMIT 1")) { 
echo mysqli_fetch_row($result)[0]; 
mysqli_free_result($result); 
} 
mysqli_close($link); 
?> 
</p> 
</body> 
</html> 
Simple test, no concurrency 
152.21 req/s 
Simple test, concurrency 
116.98 req/s 
Concurrency & KeepAlive 
165.25 req/s 
Simple test, no concurrency 
(Accept-Encoding: gzip) 
122.06 req/s 
Simple test, concurrency 
(Accept-Encoding: gzip) 
252.50 req/s 
Concurrency & KeepAlive 
(Accept-Encoding: gzip) 
288.17 req/s 
8
Test3.php (QCache + pconnect) 
<html> 
<head> 
<title>Test 3</title> 
</head> 
<body> 
<p> 
<?php 
require_once('defaults.php'); 
$link = mysqli_connect("p:$mysql_server", 
$mysql_user, 
$mysql_password,$mysql_database) or die 
("Error " . mysqli_error($link)); 
if ($result = mysqli_query($link, "SELECT 
temperature FROM oregon_data ORDER BY 
receiver_timestamp DESC LIMIT 1")) { 
echo mysqli_fetch_row($result)[0]; 
mysqli_free_result($result); 
} 
mysqli_close($link); 
?> 
</p> 
</body> 
</html> 
Simple test, no concurrency 
177.35 req/s 
Simple test, concurrency 
243.24 req/s 
Concurrency & KeepAlive 
484.15 req/s 
Simple test, no concurrency 
(Accept-Encoding: gzip) 
176.79 req/s 
Simple test, concurrency 
(Accept-Encoding: gzip) 
325.63 req/s 
Concurrency & KeepAlive 
(Accept-Encoding: gzip) 
388.58 req/s 
9
Let's try varnish 
varnishd -a :8080  
-s malloc,200M  
-f /etc/varnish.vcl  
-T 127.0.0.1:8081  
-u apache -g apache  
-t 120 
10
Let's try varnish 
varnishd -a :8080  
-s malloc,200M  
-f /etc/varnish.vcl  
-T 127.0.0.1:8081  
-u apache -g apache  
-t 120 
Simple test, no concurrency 
465.20 req/s 
Simple test, concurrency 
1053.24 req/s 
Concurrency & KeepAlive 
958.43 req/s 
Simple test, no concurrency 
(Accept-Encoding: gzip) 
454.48 req/s 
Simple test, concurrency 
(Accept-Encoding: gzip) 
948.18 req/s 
Concurrency & KeepAlive 
(Accept-Encoding: gzip) 
2361.02 req/s 
11
Obligatory Graph "Lies, damned lies, and statistics" (Mark Twain) 
12
Varnish Control Language (VCL) 
https://www.varnish-software.com/static/book/VCL_Basics.html 
13
14
15
1 vcl 4.0; 
2 # Based on: https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/ 
blob/master/default.vcl 
3 # Corrected & improved for 4.0.2 by jnerin@gmail.com 
4 import std; 
5 import directors; 
6 backend server1 { # Define one backend 
7 .host = "127.0.0.1"; # IP or Hostname of backend 
8 .port = "80"; # Port Apache or whatever is listening 
9 .max_connections = 300; # That's it 
10 .probe = { 
11 #.url = "/"; # short easy way (GET /) 
12 # We prefer to only do a HEAD / 
13 .request = 
14 "HEAD / HTTP/1.1" 
15 "Host: localhost" 
16 "Connection: close"; 
17 .interval = 5s; # check the health of each backend every 5 seconds 
18 .timeout = 1s; # timing out after 1 second. 
19 # If 3 out of the last 5 polls succeeded the backend is considered healthy, 
otherwise it will be marked as sick 
20 .window = 5; 
21 .threshold = 3; 
22 } 
23 .first_byte_timeout = 300s; # How long to wait before we receive a first byte from 
our backend? 
24 .connect_timeout = 5s; # How long to wait for a backend connection? 
25 .between_bytes_timeout = 2s; # How long to wait between bytes received from our 
backend? 
26 } 
27 acl purge { 
28 # ACL we'll use later to allow purges 
29 "localhost"; 
30 "127.0.0.1"; 
31 "::1"; 
32 } 
16
34 /* 
35 acl editors { 
36 # ACL to honor the "Cache-Control: no-cache" header to force a refresh but only from selected IPs 
37 "localhost"; 
38 "127.0.0.1"; 
39 "::1"; 
40 } 
41 */ 
42 
43 sub vcl_init { 
44 # Called when VCL is loaded, before any requests pass through it. Typically used to initialize 
VMODs. 
45 
46 new vdir = directors.round_robin(); 
47 vdir.add_backend(server1); 
48 # vdir.add_backend(server...); 
49 # vdir.add_backend(servern); 
50 } 
51 
52 sub vcl_recv { 
53 # Called at the beginning of a request, after the complete request has been received and parsed. 
Its purpose is to decide whether or not to serve the request, how to do it, and, if applicable, which 
backend to use. 
54 # also used to modify the request 
55 
56 set req.backend_hint = vdir.backend(); # send all traffic to the vdir director 
57 
58 if (req.restarts == 0) { 
59 if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For 
header 
60 set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; 
61 } else { 
62 set req.http.X-Forwarded-For = client.ip; 
63 } 
64 } 17
66 # Normalize the header, remove the port (in case you're testing this on various TCP ports) 
67 set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); 
68 
69 # Normalize the query arguments 
70 set req.url = std.querysort(req.url); 
71 
72 # Allow purging 
73 if (req.method == "PURGE") { 
74 if (!client.ip ~ purge) { # purge is the ACL defined at the begining 
75 # Not from an allowed IP? Then die with an error. 
76 return (synth(405, "This IP is not allowed to send PURGE requests.")); 
77 } 
78 # If you got this stage (and didn't error out above), purge the cached result 
79 return (purge); 
80 } 
81 
82 # Only deal with "normal" types 
83 if (req.method != "GET" && 
84 req.method != "HEAD" && 
85 req.method != "PUT" && 
86 req.method != "POST" && 
87 req.method != "TRACE" && 
88 req.method != "OPTIONS" && 
89 req.method != "PATCH" && 
90 req.method != "DELETE") { 
91 /* Non-RFC2616 or CONNECT which is weird. */ 
92 return (pipe); 
93 } 
94 
95 # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example- 
websockets.html) 
96 if (req.http.Upgrade ~ "(?i)websocket") { 
97 return (pipe); 
98 } 
18
Effect of set req.url = std.querysort(req.url); 
$ GET -de "http://test:8080/varnish.vcl.html?q1=1&q2=2&q3=3" |egrep 
"(Cache|Age|ETag|Expires|Date)" 
Cache-Control: max-age=14400 
Date: Wed, 08 Oct 2014 14:25:28 GMT 
Age: 984 
ETag: W/"3d838b6-b4f1-504e9efa40148" 
Expires: Wed, 08 Oct 2014 18:25:28 GMT 
Client-Date: Wed, 08 Oct 2014 14:41:53 GMT 
X-Cache: HIT 
X-Cache-Hits: 5 
$ GET -de "http://test:8080/varnish.vcl.html?q2=2&q1=1&q3=3" |egrep 
"(Cache|Age|ETag|Expires|Date)" 
Cache-Control: max-age=14400 
Date: Wed, 08 Oct 2014 14:25:28 GMT 
Age: 994 
ETag: W/"3d838b6-b4f1-504e9efa40148" 
Expires: Wed, 08 Oct 2014 18:25:28 GMT 
Client-Date: Wed, 08 Oct 2014 14:42:02 GMT 
X-Cache: HIT 
X-Cache-Hits: 6 
19
100 # Only cache GET or HEAD requests. This makes sure the POST requests are always passed. 
101 if (req.method != "GET" && req.method != "HEAD") { 
102 return (pass); 
103 } 
104 
105 # Some generic URL manipulation, useful for all templates that follow 
106 # First remove the Google Analytics added parameters, useless for our backend 
107 if (req.url ~ "(?|&) 
(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") { 
108 set req.url = regsuball(req.url, "& 
(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_-.%25]+)", ""); 
109 set req.url = regsuball(req.url, "? 
(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_-.%25]+)", "?"); 
110 set req.url = regsub(req.url, "?&", "?"); 
111 set req.url = regsub(req.url, "?$", ""); 
112 } 
113 
114 # Strip hash, server doesn't need it. 
115 if (req.url ~ "#") { 
116 set req.url = regsub(req.url, "#.*$", ""); 
117 } 
118 
119 # Strip a trailing ? if it exists 
120 if (req.url ~ "?$") { 
121 set req.url = regsub(req.url, "?$", ""); 
122 } 
20
124 # Some generic cookie manipulation, useful for all templates that follow 
125 # Remove the "has_js" cookie 
126 set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", ""); 
127 
128 # Remove any Google Analytics based cookies 
129 set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", ""); 
130 set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", ""); 
131 set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", ""); 
132 set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", ""); 
133 set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", ""); 
134 
135 # Remove the Quant Capital cookies (added by some plugin, all __qca) 
136 set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", ""); 
137 
138 # Remove the AddThis cookies 
139 set req.http.Cookie = regsuball(req.http.Cookie, "__atuvc=[^;]+(; )?", ""); 
140 
141 # Remove a ";" prefix in the cookie if present 
142 set req.http.Cookie = regsuball(req.http.Cookie, "^;s*", ""); 
143 
144 # Are there cookies left with only spaces or that are empty? 
145 if (req.http.cookie ~ "^s*$") { 
146 unset req.http.cookie; 
147 } 
21
149 # Normalize Accept-Encoding header 
150 # straight from the manual: https://www.varnish-cache.org/docs/3.0/tutorial/vary.html 
151 # TODO: Test if it's still needed, Varnish 4 now does this by itself if http_gzip_support = 
on 
152 # https://www.varnish-cache.org/docs/trunk/users-guide/compression.html 
153 # https://www.varnish-cache.org/docs/trunk/phk/gzip.html 
154 if (req.http.Accept-Encoding) { 
155 if (req.url ~ ".(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { 
156 # No point in compressing these 
157 unset req.http.Accept-Encoding; 
158 } elsif (req.http.Accept-Encoding ~ "gzip") { 
159 set req.http.Accept-Encoding = "gzip"; 
160 } elsif (req.http.Accept-Encoding ~ "deflate") { 
161 set req.http.Accept-Encoding = "deflate"; 
162 } else { 
163 # unkown algorithm 
164 unset req.http.Accept-Encoding; 
165 } 
166 } 
167 
168 if (req.http.Cache-Control ~ "(?i)no-cache") { 
169 #if (req.http.Cache-Control ~ "(?i)no-cache" && client.ip ~ editors) { # create the acl 
editors if you want to restrict the Ctrl-F5 
170 # http://varnish.projects.linpro.no/wiki/VCLExampleEnableForceRefresh 
171 # Ignore requests via proxy caches and badly behaved crawlers 
172 # like msnbot that send no-cache with every request. 
173 if (! (req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) { 
174 #set req.hash_always_miss = true; # Doesn't seems to refresh the object in 
the cache 
175 return(purge); # Couple this with restart in vcl_purge and X-Purge header 
to avoid loops 
176 } 
177 } 
22
179 # Large static files are delivered directly to the end-user without 
180 # waiting for Varnish to fully read the file first. 
181 # Varnish 4 fully supports Streaming, so set do_stream in vcl_backend_response() 
182 if (req.url ~ "^[^?]*.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av]) 
(?.*)?$") { 
183 unset req.http.Cookie; 
184 return (hash); 
185 } 
186 
187 # Remove all cookies for static files 
188 # A valid discussion could be held on this line: do you really need to cache static files 
that don't cause load? Only if you have memory left. 
189 # Sure, there's disk I/O, but chances are your OS will already have these files in their 
buffers (thus memory). 
190 # Before you blindly enable this, have a read here: http://mattiasgeniar. 
be/2012/11/28/stop-caching-static-files/ 
191 if (req.url ~ "^[^?]*. 
(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|pdf|png|rtf|swf|txt|woff|xml)(?.*)?$") { 
192 unset req.http.Cookie; 
193 return (hash); 
194 } 
195 
196 # Send Surrogate-Capability headers to announce ESI support to backend 
197 set req.http.Surrogate-Capability = "key=ESI/1.0"; 
198 
199 if (req.http.Authorization) { 
200 # Not cacheable by default 
201 return (pass); 
202 } 
203 
204 return (hash); 
205 } 
23
207 sub vcl_pipe { 
208 # Called upon entering pipe mode. In this mode, the request is passed on to the backend, and any 
further data from both the client and backend is passed on unaltered until either end closes the 
connection. Basically, Varnish will degrade into a simple TCP proxy, shuffling bytes back and forth. 
For a connection in pipe mode, no other VCL subroutine will ever get called after vcl_pipe. 
209 
210 # Note that only the first request to the backend will have 
211 # X-Forwarded-For set. If you use X-Forwarded-For and want to 
212 # have it set for all requests, make sure to have: 
213 # set bereq.http.connection = "close"; 
214 # here. It is not set by default as it might break some broken web 
215 # applications, like IIS with NTLM authentication. 
216 
217 #set bereq.http.Connection = "Close"; 
218 
219 # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example- 
websockets.html) 
220 if (req.http.upgrade) { 
221 set bereq.http.upgrade = req.http.upgrade; 
222 } 
223 
224 return (pipe); 
225 } 
226 
227 sub vcl_pass { 
228 # Called upon entering pass mode. In this mode, the request is passed on to the backend, and the 
backend's response is passed on to the client, but is not entered into the cache. Subsequent requests 
submitted over the same client connection are handled normally. 
229 
230 # return (pass); 
231 } 
24
233 # The data on which the hashing will take place 
234 sub vcl_hash { 
235 # Called after vcl_recv to create a hash value for the request. This is used as a key to look up 
the object in Varnish. 
236 
237 hash_data(req.url); 
238 
239 if (req.http.host) { 
240 hash_data(req.http.host); 
241 } else { 
242 hash_data(server.ip); 
243 } 
244 
245 # hash cookies for requests that have them 
246 if (req.http.Cookie) { 
247 hash_data(req.http.Cookie); 
248 } 
249 } 
250 
251 sub vcl_hit { 
252 # Called when a cache lookup is successful. 
253 
254 if (obj.ttl >= 0s) { 
255 # A pure unadultered hit, deliver it 
256 return (deliver); 
257 } 
25
259 # https://www.varnish-cache.org/docs/trunk/users-guide/vcl-grace.html 
260 # When several clients are requesting the same page Varnish will send one request to the 
backend and place the others on hold while fetching one copy from the backend. In some products this 
is called request coalescing and Varnish does this automatically. 
261 # If you are serving thousands of hits per second the queue of waiting requests can get 
huge. There are two potential problems - one is a thundering herd problem - suddenly releasing a 
thousand threads to serve content might send the load sky high. Secondly - nobody likes to wait. To 
deal with this we can instruct Varnish to keep the objects in cache beyond their TTL and to serve the 
waiting requests somewhat stale content. 
262 
269 # We have no fresh fish. Lets look at the stale ones. 
270 if (std.healthy(req.backend_hint)) { 
271 # Backend is healthy. Limit age to 10s. 
272 if (obj.ttl + 10s > 0s) { 
273 #set req.http.grace = "normal(limited)"; 
274 return (deliver); 
275 } else { 
276 # No candidate for grace. Fetch a fresh object. 
277 return(fetch); 
278 } 
279 } else { 
280 # backend is sick - use full grace 
281 if (obj.ttl + obj.grace > 0s) { 
282 #set req.http.grace = "full"; 
283 return (deliver); 
284 } else { 
285 # no graced object. 
286 return (fetch); 
287 } 
288 } 
289 
290 
291 # fetch & deliver once we get the result 
292 return (fetch); # Dead code, keep as a safeguard 
293 } 26
295 sub vcl_miss { 
296 # Called after a cache lookup if the requested document was not found in the cache. Its purpose is 
to decide whether or not to attempt to retrieve the document from the backend, and which backend to 
use. 
297 
298 return (fetch); 
299 } 
300 
301 # Handle the HTTP request coming from our backend 
302 sub vcl_backend_response { 
303 # Called after the response headers has been successfully retrieved from the backend. 
304 
305 # Pause ESI request and remove Surrogate-Control header 
306 if (beresp.http.Surrogate-Control ~ "ESI/1.0") { 
307 unset beresp.http.Surrogate-Control; 
308 set beresp.do_esi = true; 
309 } 
310 
311 # Enable cache for all static files 
312 # The same argument as the static caches from above: monitor your cache size, if you get 
data nuked out of it, consider giving up the static file cache. 
313 # Before you blindly enable this, have a read here: http://mattiasgeniar. 
be/2012/11/28/stop-caching-static-files/ 
314 if (bereq.url ~ "^[^?]*.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|mp[34] 
|pdf|png|rar|rtf|swf|tar|tgz|txt|wav|woff|xml|zip)(?.*)?$") { 
315 unset beresp.http.set-cookie; 
316 } 
27
319 # Large static files are delivered directly to the end-user without 
320 # waiting for Varnish to fully read the file first. 
321 # Varnish 4 fully supports Streaming, so use streaming here to avoid locking. 
322 if (bereq.url ~ "^[^?]*.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av]) 
(?.*)?$") { 
323 unset beresp.http.set-cookie; 
324 set beresp.do_stream = true; # Check memory usage it'll grow in fetch_chunksize 
blocks (128k by default) if 
325 # the backend doesn't send a Content-Length header, 
so only enable it for big objects 
326 set beresp.do_gzip = false; # Don't try to compress it for storage 
327 } 
329 # Sometimes, a 301 or 302 redirect formed via Apache's mod_rewrite can mess with the HTTP 
port that is being passed along. 
330 # This often happens with simple rewrite rules in a scenario where Varnish runs on :80 and 
Apache on :8080 on the same box. 
331 # A redirect can then often redirect the end-user to a URL on :8080, where it should be : 
80. 
332 # This may need finetuning on your setup. 
333 # 
334 # To prevent accidental replace, we only filter the 301/302 redirects for now. 
335 if (beresp.status == 301 || beresp.status == 302) { 
336 set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", ""); 
337 } 
339 # Disable queue coalescence for uncacheable objects 
340 if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") { 
341 set beresp.uncacheable = true; # hit_for_pass 
342 set beresp.ttl = 120s; # Remeber this 
343 return (deliver); 
344 } 
346 # Allow stale content, in case the backend goes down. 
347 # make Varnish keep all objects for 6 hours beyond their TTL 
348 set beresp.grace = 6h; 
350 return (deliver); 
351 } 28
353 # The routine when we deliver the HTTP request to the user 
354 # Last chance to modify headers that are sent to the client 
355 sub vcl_deliver { 
356 # Called before a cached object is delivered to the client. 
357 
358 if (obj.hits > 0) { # Add debug header to see if it's a HIT/MISS and the number of hits, 
disable when not needed 
359 set resp.http.X-Cache = "HIT"; 
360 } else { 
361 set resp.http.X-Cache = "MISS"; 
362 } 
363 # Please note that obj.hits behaviour changed in 4.0, now it counts per objecthead, not per 
object 
364 # and obj.hits may not be reset in some cases where bans are in use. See bug 1492 for 
details. 
365 # So take hits with a grain of salt 
366 set resp.http.X-Cache-Hits = obj.hits; 
368 # Remove some headers: PHP version 
369 unset resp.http.X-Powered-By; 
371 # Remove some headers: Apache version & OS 
372 unset resp.http.Server; 
373 unset resp.http.X-Drupal-Cache; 
374 unset resp.http.X-Varnish; 
375 unset resp.http.Via; 
376 unset resp.http.Link; 
378 return (deliver); 
379 } 
380 
381 sub vcl_purge { 
382 # restart request 
383 set req.http.X-Purge = "Yes"; 
384 return(restart); 
385 } 
29
387 sub vcl_synth { 
388 if (resp.status == 720) { 
389 # We use this special error status 720 to force redirects with 301 (permanent) 
redirects 
390 # To use this, call the following from anywhere in vcl_recv: error 720 "http: 
//host/new.html" 
391 set resp.http.Location = resp.reason; 
392 set resp.status = 301; 
393 return (deliver); 
394 } elseif (resp.status == 721) { 
395 # And we use error status 721 to force redirects with a 302 (temporary) redirect 
396 # To use this, call the following from anywhere in vcl_recv: error 720 "http: 
//host/new.html" 
397 set resp.http.Location = resp.reason; 
398 set resp.status = 302; 
399 return (deliver); 
400 } 
401 
402 return (deliver); 
403 } 
404 
405 
406 sub vcl_fini { 
407 # Called when VCL is discarded only after all requests have exited the VCL. Typically used to 
clean up VMODs. 
408 
409 return (ok); 
410 } 
30
sub vcl_recv { 
if (req.url ~ "^/varnish/") { 
# Lame example to generate content, look down in vcl_synth for status 820 
return (synth(820, "Test")); 
} 
} 
sub vcl_synth { 
if (resp.status == 820) { 
# Lame example showing how to generate synthetic content. 
# Usually to do this you would use a vmod from https://www.varnish-cache.org/vmods 
# to do things like memcache/redis/database/... lookups and return meaningful things 
# expected url /varnish/parameter1/min/max/ -> /varnish/real_random_api/8/32/ 
set resp.http.Content-Type = "text/plain; charset=utf-8"; 
set req.http.X-parameter1 = regsub(req.url, "^/varnish/(.*?)/.*", "1"); 
set req.http.X-min = regsub(req.url, "^/varnish/.*?/(.*?)/.*", "1"); 
set req.http.X-max = regsub(req.url, "^/varnish/.*?/.*?/(.*?)/.*", "1"); 
synthetic("You are " + client.ip + {" 
url: "} + req.url + {" 
reason: "} + resp.reason + {" 
1st parameter: "} + req.http.X-parameter1 + {" 
Have your random number between "} + req.http.X-min + " and " + req.http.X-max + " : " + std.random 
(std.real(req.http.X-min, 0), std.real(req.http.X-max, 100)) + {" 
End 
"}); 
set resp.status = 200; # Be careful to set it after using resp.reason or it'll overwrite it 
return (deliver); 
} 
return (deliver); 
} 
31
Playing with vcl_synth 
$ GET -E http://localhost:8080/varnish/reason/-8/42/ 
GET http://localhost:8080/varnish/reason/-8/42/ 
User-Agent: lwp-request/6.03 libwww-perl/6.05 
200 OK 
Connection: close 
Date: Mon, 24 Nov 2014 15:26:12 GMT 
Accept-Ranges: bytes 
Server: Varnish 
Content-Length: 133 
Content-Type: text/plain; charset=utf-8 
Client-Date: Mon, 24 Nov 2014 15:26:12 GMT 
Client-Peer: 127.0.0.1:8080 
Client-Response-Num: 1 
X-Varnish: 42 
You are 127.0.0.1 
url: /varnish/reason/-8/42/ 
reason: Test 
1st parameter: reason 
Have a random number between -8 and 42 : -2.204 
End 
32
But that's not enough: 
$ GET -e http://test/test1.html 
200 OK 
Connection: close 
Date: Fri, 03 Oct 2014 16:37:59 GMT 
Accept-Ranges: bytes 
ETag: "3d838cc-51-504816b16fe6a" 
Server: Apache 
Vary: Accept-Encoding 
Content-Length: 81 
Content-Type: text/html 
Last-Modified: Fri, 03 Oct 2014 09:32:57 GMT 
33
But that's not enough: 
# http://httpd.apache.org/docs/2.0/mod/mod_expires.html 
ExpiresActive On 
ExpiresByType image/gif "access plus 4 days" 
#<FilesMatch ".(gif|jpe?g|png)$"> 
# Header merge Cache-Control "public" # Default anyway 
# ExpiresDefault "access plus 4 days" 
#</FilesMatch> 
ExpiresByType image/jpg "access plus 4 days" 
ExpiresByType image/jpeg "access plus 4 days" 
ExpiresByType image/png "access plus 4 days" 
ExpiresByType image/x-icon "access plus 4 days" 
ExpiresByType text/css "access plus 3 days" 
ExpiresByType application/x-javascript "access plus 3 days" 
ExpiresByType text/html "access plus 4 hours" 
ExpiresByType application/xml "access plus 1 hours" 
34
But that's not enough: 
$ GET -e http://test/test1.html 
200 OK 
Cache-Control: max-age=14400 
Connection: close 
Date: Fri, 03 Oct 2014 17:37:42 GMT 
Accept-Ranges: bytes 
ETag: "3d838cc-51-504816b16fe6a" 
Server: Apache 
Vary: Accept-Encoding 
Content-Length: 81 
Content-Type: text/html 
Expires: Fri, 03 Oct 2014 21:37:42 GMT 
Last-Modified: Fri, 03 Oct 2014 09:32:57 GMT 
35
Numbers on faster hardware 
(AMD FX(tm)-8120 Eight-Core Processor 32GB RAM) 
/usr/sbin/ab2 -n 500000 -c 200 -k -H "Accept-encoding: gzip" "http: 
//localhost/prueba.html" 
Requests per second: 24318.71 [#/sec] (mean) 
Time per request: 8.224 [ms] (mean) 
Time per request: 0.041 [ms] (mean, across all concurrent 
requests) 
Transfer rate: 8161.06 [Kbytes/sec] received 
/usr/sbin/ab2 -n 500000 -c 200 -k -H "Accept-encoding: gzip" "http: 
//localhost:8080/prueba.html" 
Requests per second: 25780.13 [#/sec] (mean) 
Time per request: 7.758 [ms] (mean) 
Time per request: 0.039 [ms] (mean, across all concurrent 
requests) 
Transfer rate: 8611.04 [Kbytes/sec] received 36
Resources 
● https://www.varnish-cache.org/docs 
○ https://www.varnish-software.com/static/book/VCL_Basics.html 
○ https://www.varnish-cache.org/trac/wiki 
● High Performance Browser Networking by Ilya Grigorik (http: 
//chimera.labs.oreilly.com/books/1230000000545/index.html) 
● Caching in HTTP (http://www.w3.org/Protocols/rfc2616/rfc2616- 
sec13.html) 
● The only moment you should ever cache static files is if you have 
memory to spare (http://mattiasgeniar.be/2012/11/28/stop-caching-static- 
files/) 
● How to Use Varnish to Speed up my Website (http://symfony. 
com/doc/current/cookbook/cache/varnish.html) 
● https://www.varnish-cache.org/vmods (redis, memcache, MySQL, 
PostgreSQL, ratelimit, device detection, json, auth, ...) 
37
HTTP/1.1 200 OK 
38

Contenu connexe

Tendances

Varnish @ Velocity Ignite
Varnish @ Velocity IgniteVarnish @ Velocity Ignite
Varnish @ Velocity IgniteArtur Bergman
 
MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)Seungmin Yu
 
Acus08 Advanced Load Balancing Apache2.2
Acus08 Advanced Load Balancing Apache2.2Acus08 Advanced Load Balancing Apache2.2
Acus08 Advanced Load Balancing Apache2.2Jim Jagielski
 
Rails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeRails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeMichael May
 
My sql failover test using orchestrator
My sql failover test  using orchestratorMy sql failover test  using orchestrator
My sql failover test using orchestratorYoungHeon (Roy) Kim
 
2016 W3C Conference #4 : ANGULAR + ES6
2016 W3C Conference #4 : ANGULAR + ES62016 W3C Conference #4 : ANGULAR + ES6
2016 W3C Conference #4 : ANGULAR + ES6양재동 코드랩
 
자바 성능 강의
자바 성능 강의자바 성능 강의
자바 성능 강의Terry Cho
 
Redis sentinelinternals deview
Redis sentinelinternals deviewRedis sentinelinternals deview
Redis sentinelinternals deviewDaeMyung Kang
 
Wait Events 10g
Wait Events 10gWait Events 10g
Wait Events 10gsagai
 
How to cook lettuce @Java casual
How to cook lettuce @Java casualHow to cook lettuce @Java casual
How to cook lettuce @Java casualGo Hagiwara
 
[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기
[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기
[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기NAVER D2
 
Oracle 10g Performance: chapter 09 enqueues
Oracle 10g Performance: chapter 09 enqueuesOracle 10g Performance: chapter 09 enqueues
Oracle 10g Performance: chapter 09 enqueuesKyle Hailey
 
Java profiling Do It Yourself (jug.msk.ru 2016)
Java profiling Do It Yourself (jug.msk.ru 2016)Java profiling Do It Yourself (jug.msk.ru 2016)
Java profiling Do It Yourself (jug.msk.ru 2016)aragozin
 
UKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction LocksUKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction LocksKyle Hailey
 
MySQL replication & cluster
MySQL replication & clusterMySQL replication & cluster
MySQL replication & clusterelliando dias
 
Мастер-класс "Логическая репликация и Avito" / Константин Евтеев, Михаил Тюр...
Мастер-класс "Логическая репликация и Avito" / Константин Евтеев,  Михаил Тюр...Мастер-класс "Логическая репликация и Avito" / Константин Евтеев,  Михаил Тюр...
Мастер-класс "Логическая репликация и Avito" / Константин Евтеев, Михаил Тюр...Ontico
 

Tendances (19)

Varnish @ Velocity Ignite
Varnish @ Velocity IgniteVarnish @ Velocity Ignite
Varnish @ Velocity Ignite
 
MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)
 
Query logging with proxysql
Query logging with proxysqlQuery logging with proxysql
Query logging with proxysql
 
Acus08 Advanced Load Balancing Apache2.2
Acus08 Advanced Load Balancing Apache2.2Acus08 Advanced Load Balancing Apache2.2
Acus08 Advanced Load Balancing Apache2.2
 
Rails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeRails Caching Secrets from the Edge
Rails Caching Secrets from the Edge
 
My sql failover test using orchestrator
My sql failover test  using orchestratorMy sql failover test  using orchestrator
My sql failover test using orchestrator
 
2016 W3C Conference #4 : ANGULAR + ES6
2016 W3C Conference #4 : ANGULAR + ES62016 W3C Conference #4 : ANGULAR + ES6
2016 W3C Conference #4 : ANGULAR + ES6
 
Apache ZooKeeper
Apache ZooKeeperApache ZooKeeper
Apache ZooKeeper
 
자바 성능 강의
자바 성능 강의자바 성능 강의
자바 성능 강의
 
Redis sentinelinternals deview
Redis sentinelinternals deviewRedis sentinelinternals deview
Redis sentinelinternals deview
 
Wait Events 10g
Wait Events 10gWait Events 10g
Wait Events 10g
 
How to cook lettuce @Java casual
How to cook lettuce @Java casualHow to cook lettuce @Java casual
How to cook lettuce @Java casual
 
[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기
[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기
[Hello world 오픈세미나]varnish로 웹서버성능 향상시키기
 
Qt Network Explained (Portuguese)
Qt Network Explained (Portuguese)Qt Network Explained (Portuguese)
Qt Network Explained (Portuguese)
 
Oracle 10g Performance: chapter 09 enqueues
Oracle 10g Performance: chapter 09 enqueuesOracle 10g Performance: chapter 09 enqueues
Oracle 10g Performance: chapter 09 enqueues
 
Java profiling Do It Yourself (jug.msk.ru 2016)
Java profiling Do It Yourself (jug.msk.ru 2016)Java profiling Do It Yourself (jug.msk.ru 2016)
Java profiling Do It Yourself (jug.msk.ru 2016)
 
UKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction LocksUKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction Locks
 
MySQL replication & cluster
MySQL replication & clusterMySQL replication & cluster
MySQL replication & cluster
 
Мастер-класс "Логическая репликация и Avito" / Константин Евтеев, Михаил Тюр...
Мастер-класс "Логическая репликация и Avito" / Константин Евтеев,  Михаил Тюр...Мастер-класс "Логическая репликация и Avito" / Константин Евтеев,  Михаил Тюр...
Мастер-класс "Логическая репликация и Avito" / Константин Евтеев, Михаил Тюр...
 

En vedette

Caching with varnish
Caching with varnishCaching with varnish
Caching with varnish90kts
 
Surfaces&display varnishes v1.1
Surfaces&display varnishes v1.1Surfaces&display varnishes v1.1
Surfaces&display varnishes v1.1cassart_training
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Jeroen van Dijk
 

En vedette (7)

Varnish - PLNOG 4
Varnish - PLNOG 4Varnish - PLNOG 4
Varnish - PLNOG 4
 
Caching with varnish
Caching with varnishCaching with varnish
Caching with varnish
 
Varnish Extend demo
Varnish Extend demoVarnish Extend demo
Varnish Extend demo
 
Surfaces&display varnishes v1.1
Surfaces&display varnishes v1.1Surfaces&display varnishes v1.1
Surfaces&display varnishes v1.1
 
Varnish, the high performance valhalla?
Varnish, the high performance valhalla?Varnish, the high performance valhalla?
Varnish, the high performance valhalla?
 
Plastering and pointing
Plastering and pointingPlastering and pointing
Plastering and pointing
 
Report on varnish
Report on varnishReport on varnish
Report on varnish
 

Similaire à Varnish presentation for the Symfony Zaragoza user group

Altitude SF 2017: Debugging Fastly VCL 101
Altitude SF 2017: Debugging Fastly VCL 101Altitude SF 2017: Debugging Fastly VCL 101
Altitude SF 2017: Debugging Fastly VCL 101Fastly
 
X64服务器 lnmp服务器部署标准 new
X64服务器 lnmp服务器部署标准 newX64服务器 lnmp服务器部署标准 new
X64服务器 lnmp服务器部署标准 newYiwei Ma
 
Salesforce at Stacki Atlanta Meetup February 2016
Salesforce at Stacki Atlanta Meetup February 2016Salesforce at Stacki Atlanta Meetup February 2016
Salesforce at Stacki Atlanta Meetup February 2016StackIQ
 
VCLをTDDで書いてデプロイする
VCLをTDDで書いてデプロイするVCLをTDDで書いてデプロイする
VCLをTDDで書いてデプロイするKengo HAMASAKI
 
Jvm operation casual talks
Jvm operation casual talksJvm operation casual talks
Jvm operation casual talksYusaku Watanabe
 
Solving anything in VCL
Solving anything in VCLSolving anything in VCL
Solving anything in VCLFastly
 
Altitude San Francisco 2018: Programming the Edge
Altitude San Francisco 2018: Programming the EdgeAltitude San Francisco 2018: Programming the Edge
Altitude San Francisco 2018: Programming the EdgeFastly
 
(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014
(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014
(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014Amazon Web Services
 
Live deployment, ci, drupal
Live deployment, ci, drupalLive deployment, ci, drupal
Live deployment, ci, drupalAndrii Podanenko
 
Ch10.애플리케이션 서버의 병목_발견_방법
Ch10.애플리케이션 서버의 병목_발견_방법Ch10.애플리케이션 서버의 병목_발견_방법
Ch10.애플리케이션 서버의 병목_발견_방법Minchul Jung
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Alexey Fyodorov
 
In Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry OsborneIn Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry OsborneEnkitec
 
Oracle Database In-Memory Option in Action
Oracle Database In-Memory Option in ActionOracle Database In-Memory Option in Action
Oracle Database In-Memory Option in ActionTanel Poder
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalabilityWim Godden
 

Similaire à Varnish presentation for the Symfony Zaragoza user group (20)

Altitude SF 2017: Debugging Fastly VCL 101
Altitude SF 2017: Debugging Fastly VCL 101Altitude SF 2017: Debugging Fastly VCL 101
Altitude SF 2017: Debugging Fastly VCL 101
 
Memcached Study
Memcached StudyMemcached Study
Memcached Study
 
Run Node Run
Run Node RunRun Node Run
Run Node Run
 
X64服务器 lnmp服务器部署标准 new
X64服务器 lnmp服务器部署标准 newX64服务器 lnmp服务器部署标准 new
X64服务器 lnmp服务器部署标准 new
 
Salesforce at Stacki Atlanta Meetup February 2016
Salesforce at Stacki Atlanta Meetup February 2016Salesforce at Stacki Atlanta Meetup February 2016
Salesforce at Stacki Atlanta Meetup February 2016
 
bluespec talk
bluespec talkbluespec talk
bluespec talk
 
VCLをTDDで書いてデプロイする
VCLをTDDで書いてデプロイするVCLをTDDで書いてデプロイする
VCLをTDDで書いてデプロイする
 
Jvm operation casual talks
Jvm operation casual talksJvm operation casual talks
Jvm operation casual talks
 
Solving anything in VCL
Solving anything in VCLSolving anything in VCL
Solving anything in VCL
 
Curator intro
Curator introCurator intro
Curator intro
 
Debugging varnish
Debugging varnishDebugging varnish
Debugging varnish
 
Altitude San Francisco 2018: Programming the Edge
Altitude San Francisco 2018: Programming the EdgeAltitude San Francisco 2018: Programming the Edge
Altitude San Francisco 2018: Programming the Edge
 
Rails Performance
Rails PerformanceRails Performance
Rails Performance
 
(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014
(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014
(SDD402) Amazon ElastiCache Deep Dive | AWS re:Invent 2014
 
Live deployment, ci, drupal
Live deployment, ci, drupalLive deployment, ci, drupal
Live deployment, ci, drupal
 
Ch10.애플리케이션 서버의 병목_발견_방법
Ch10.애플리케이션 서버의 병목_발견_방법Ch10.애플리케이션 서버의 병목_발견_방법
Ch10.애플리케이션 서버의 병목_발견_방법
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)
 
In Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry OsborneIn Memory Database In Action by Tanel Poder and Kerry Osborne
In Memory Database In Action by Tanel Poder and Kerry Osborne
 
Oracle Database In-Memory Option in Action
Oracle Database In-Memory Option in ActionOracle Database In-Memory Option in Action
Oracle Database In-Memory Option in Action
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 

Dernier

How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfIdiosysTechnologies1
 

Dernier (20)

How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
Best Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdfBest Web Development Agency- Idiosys USA.pdf
Best Web Development Agency- Idiosys USA.pdf
 

Varnish presentation for the Symfony Zaragoza user group

  • 1. r.v. var·nished, var·nish·ing, var·nish·es 1. To cover with varnish. 2. To give a smooth and glossy finish to. 3. To give a deceptively attractive appearance to; gloss over. by jnerin 1
  • 2. Server (cubietruck) ● AllWinnerTech SOC A20 ○ ARM® Cortex™-A7 Dual-Core ● 2GB ram ● SAMSUNG SpinPoint F2 EG 1.5TB sata hard disk ● 1Gb Ethernet 2
  • 3. Server (cubietruck) ● Apache 2.2.27-r4 ○ KeepAlive On ○ MaxKeepAliveRequests 100 ○ KeepAliveTimeout 15 ○ mpm worker: StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxClients 150 MaxRequestsPerChild 10000 ● PHP 5.5.16 (opcache enabled by default 64M) ● mariadb 10.0.14 (have_query_cache=YES but query_cache_size=0) 3
  • 4. Test.sh #!/bin/bash URL="$1" LOG="$URL.$(date +%Y%m%d-%H%M%S).log" HOST="test" IP="192.168.2.3:8080" REQUESTS=10000 CONCURRENCY=20 exec 6<&1 # Save STDOUT FD exec >$LOG echo "- Simple test, no concurrency" /usr/sbin/ab2 -n $REQUESTS -H "Host: $HOST" http://$IP/$URL echo "- Simple test, concurrency" /usr/sbin/ab2 -n $REQUESTS -c $CONCURRENCY -H "Host: $HOST" http://$IP/$URL echo "- Concurrency & KeepAlive" /usr/sbin/ab2 -k -n $REQUESTS -c $CONCURRENCY -H "Host: $HOST" http://$IP/$URL echo "- Simple test, no concurrency (Accept-Encoding: gzip)" /usr/sbin/ab2 -n $REQUESTS -H "Accept-encoding: gzip" -H "Host: $HOST" http://$IP/$URL echo "- Simple test, concurrency (Accept-Encoding: gzip)" /usr/sbin/ab2 -n $REQUESTS -c $CONCURRENCY -H "Accept-encoding: gzip" -H "Host: $HOST" http: //$IP/$URL echo "- Concurrency & KeepAlive (Accept-Encoding: gzip)" /usr/sbin/ab2 -k -n $REQUESTS -c $CONCURRENCY -H "Accept-encoding: gzip" -H "Host: $HOST" http: //$IP/$URL exec 1<&6 6<&- # Restore STDOUT FD egrep "^(-|Requests per second)" $LOG 4
  • 5. Test1.html <html> <head> <title>Test 1</title> </head> <body> <p>Test 1</p> </body> </html> Simple test, no concurrency 222.56 req/s Simple test, concurrency 197.06 req/s Concurrency & KeepAlive 679.81 req/s Simple test, no concurrency (Accept-Encoding: gzip) 232.75 req/s Simple test, concurrency (Accept-Encoding: gzip) 415.48 req/s Concurrency & KeepAlive (Accept-Encoding: gzip) 825.26 req/s 5
  • 6. Test2.php <html> <head> <title>Test 2</title> </head> <body> <p> <?php require_once('defaults.php'); $link = mysqli_connect($mysql_server, $mysql_user, $mysql_password,$mysql_database) or die ("Error " . mysqli_error($link)); if ($result = mysqli_query($link, "SELECT temperature FROM oregon_data ORDER BY receiver_timestamp DESC LIMIT 1")) { echo mysqli_fetch_row($result)[0]; mysqli_free_result($result); } mysqli_close($link); ?> </p> </body> </html> Simple test, no concurrency 120.61 req/s Simple test, concurrency 236.65 req/s Concurrency & KeepAlive 271.19 req/s Simple test, no concurrency (Accept-Encoding: gzip) 94.80 req/s Simple test, concurrency (Accept-Encoding: gzip) 108.93 req/s Concurrency & KeepAlive (Accept-Encoding: gzip) 163.97 req/s 6
  • 7. MySQL Query Cache (Qcache) mysql -e 'show global variables like "%query_cache%";show status like "Qcache%"' +------------------------------+----------+ | Variable_name | Value | +------------------------------+----------+ | have_query_cache | YES | | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 33554432 | | query_cache_strip_comments | OFF | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | +------------------------------+----------+ +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Qcache_free_blocks | 1 | | Qcache_free_memory | 33544000 | | Qcache_hits | 60030 | | Qcache_inserts | 10 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 97 | | Qcache_queries_in_cache | 1 | | Qcache_total_blocks | 4 | +-------------------------+----------+ 7
  • 8. Test2.php + QCache <html> <head> <title>Test 2</title> </head> <body> <p> <?php require_once('defaults.php'); $link = mysqli_connect($mysql_server, $mysql_user, $mysql_password,$mysql_database) or die ("Error " . mysqli_error($link)); if ($result = mysqli_query($link, "SELECT temperature FROM oregon_data ORDER BY receiver_timestamp DESC LIMIT 1")) { echo mysqli_fetch_row($result)[0]; mysqli_free_result($result); } mysqli_close($link); ?> </p> </body> </html> Simple test, no concurrency 152.21 req/s Simple test, concurrency 116.98 req/s Concurrency & KeepAlive 165.25 req/s Simple test, no concurrency (Accept-Encoding: gzip) 122.06 req/s Simple test, concurrency (Accept-Encoding: gzip) 252.50 req/s Concurrency & KeepAlive (Accept-Encoding: gzip) 288.17 req/s 8
  • 9. Test3.php (QCache + pconnect) <html> <head> <title>Test 3</title> </head> <body> <p> <?php require_once('defaults.php'); $link = mysqli_connect("p:$mysql_server", $mysql_user, $mysql_password,$mysql_database) or die ("Error " . mysqli_error($link)); if ($result = mysqli_query($link, "SELECT temperature FROM oregon_data ORDER BY receiver_timestamp DESC LIMIT 1")) { echo mysqli_fetch_row($result)[0]; mysqli_free_result($result); } mysqli_close($link); ?> </p> </body> </html> Simple test, no concurrency 177.35 req/s Simple test, concurrency 243.24 req/s Concurrency & KeepAlive 484.15 req/s Simple test, no concurrency (Accept-Encoding: gzip) 176.79 req/s Simple test, concurrency (Accept-Encoding: gzip) 325.63 req/s Concurrency & KeepAlive (Accept-Encoding: gzip) 388.58 req/s 9
  • 10. Let's try varnish varnishd -a :8080 -s malloc,200M -f /etc/varnish.vcl -T 127.0.0.1:8081 -u apache -g apache -t 120 10
  • 11. Let's try varnish varnishd -a :8080 -s malloc,200M -f /etc/varnish.vcl -T 127.0.0.1:8081 -u apache -g apache -t 120 Simple test, no concurrency 465.20 req/s Simple test, concurrency 1053.24 req/s Concurrency & KeepAlive 958.43 req/s Simple test, no concurrency (Accept-Encoding: gzip) 454.48 req/s Simple test, concurrency (Accept-Encoding: gzip) 948.18 req/s Concurrency & KeepAlive (Accept-Encoding: gzip) 2361.02 req/s 11
  • 12. Obligatory Graph "Lies, damned lies, and statistics" (Mark Twain) 12
  • 13. Varnish Control Language (VCL) https://www.varnish-software.com/static/book/VCL_Basics.html 13
  • 14. 14
  • 15. 15
  • 16. 1 vcl 4.0; 2 # Based on: https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/ blob/master/default.vcl 3 # Corrected & improved for 4.0.2 by jnerin@gmail.com 4 import std; 5 import directors; 6 backend server1 { # Define one backend 7 .host = "127.0.0.1"; # IP or Hostname of backend 8 .port = "80"; # Port Apache or whatever is listening 9 .max_connections = 300; # That's it 10 .probe = { 11 #.url = "/"; # short easy way (GET /) 12 # We prefer to only do a HEAD / 13 .request = 14 "HEAD / HTTP/1.1" 15 "Host: localhost" 16 "Connection: close"; 17 .interval = 5s; # check the health of each backend every 5 seconds 18 .timeout = 1s; # timing out after 1 second. 19 # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick 20 .window = 5; 21 .threshold = 3; 22 } 23 .first_byte_timeout = 300s; # How long to wait before we receive a first byte from our backend? 24 .connect_timeout = 5s; # How long to wait for a backend connection? 25 .between_bytes_timeout = 2s; # How long to wait between bytes received from our backend? 26 } 27 acl purge { 28 # ACL we'll use later to allow purges 29 "localhost"; 30 "127.0.0.1"; 31 "::1"; 32 } 16
  • 17. 34 /* 35 acl editors { 36 # ACL to honor the "Cache-Control: no-cache" header to force a refresh but only from selected IPs 37 "localhost"; 38 "127.0.0.1"; 39 "::1"; 40 } 41 */ 42 43 sub vcl_init { 44 # Called when VCL is loaded, before any requests pass through it. Typically used to initialize VMODs. 45 46 new vdir = directors.round_robin(); 47 vdir.add_backend(server1); 48 # vdir.add_backend(server...); 49 # vdir.add_backend(servern); 50 } 51 52 sub vcl_recv { 53 # Called at the beginning of a request, after the complete request has been received and parsed. Its purpose is to decide whether or not to serve the request, how to do it, and, if applicable, which backend to use. 54 # also used to modify the request 55 56 set req.backend_hint = vdir.backend(); # send all traffic to the vdir director 57 58 if (req.restarts == 0) { 59 if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header 60 set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; 61 } else { 62 set req.http.X-Forwarded-For = client.ip; 63 } 64 } 17
  • 18. 66 # Normalize the header, remove the port (in case you're testing this on various TCP ports) 67 set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); 68 69 # Normalize the query arguments 70 set req.url = std.querysort(req.url); 71 72 # Allow purging 73 if (req.method == "PURGE") { 74 if (!client.ip ~ purge) { # purge is the ACL defined at the begining 75 # Not from an allowed IP? Then die with an error. 76 return (synth(405, "This IP is not allowed to send PURGE requests.")); 77 } 78 # If you got this stage (and didn't error out above), purge the cached result 79 return (purge); 80 } 81 82 # Only deal with "normal" types 83 if (req.method != "GET" && 84 req.method != "HEAD" && 85 req.method != "PUT" && 86 req.method != "POST" && 87 req.method != "TRACE" && 88 req.method != "OPTIONS" && 89 req.method != "PATCH" && 90 req.method != "DELETE") { 91 /* Non-RFC2616 or CONNECT which is weird. */ 92 return (pipe); 93 } 94 95 # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example- websockets.html) 96 if (req.http.Upgrade ~ "(?i)websocket") { 97 return (pipe); 98 } 18
  • 19. Effect of set req.url = std.querysort(req.url); $ GET -de "http://test:8080/varnish.vcl.html?q1=1&q2=2&q3=3" |egrep "(Cache|Age|ETag|Expires|Date)" Cache-Control: max-age=14400 Date: Wed, 08 Oct 2014 14:25:28 GMT Age: 984 ETag: W/"3d838b6-b4f1-504e9efa40148" Expires: Wed, 08 Oct 2014 18:25:28 GMT Client-Date: Wed, 08 Oct 2014 14:41:53 GMT X-Cache: HIT X-Cache-Hits: 5 $ GET -de "http://test:8080/varnish.vcl.html?q2=2&q1=1&q3=3" |egrep "(Cache|Age|ETag|Expires|Date)" Cache-Control: max-age=14400 Date: Wed, 08 Oct 2014 14:25:28 GMT Age: 994 ETag: W/"3d838b6-b4f1-504e9efa40148" Expires: Wed, 08 Oct 2014 18:25:28 GMT Client-Date: Wed, 08 Oct 2014 14:42:02 GMT X-Cache: HIT X-Cache-Hits: 6 19
  • 20. 100 # Only cache GET or HEAD requests. This makes sure the POST requests are always passed. 101 if (req.method != "GET" && req.method != "HEAD") { 102 return (pass); 103 } 104 105 # Some generic URL manipulation, useful for all templates that follow 106 # First remove the Google Analytics added parameters, useless for our backend 107 if (req.url ~ "(?|&) (utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") { 108 set req.url = regsuball(req.url, "& (utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_-.%25]+)", ""); 109 set req.url = regsuball(req.url, "? (utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_-.%25]+)", "?"); 110 set req.url = regsub(req.url, "?&", "?"); 111 set req.url = regsub(req.url, "?$", ""); 112 } 113 114 # Strip hash, server doesn't need it. 115 if (req.url ~ "#") { 116 set req.url = regsub(req.url, "#.*$", ""); 117 } 118 119 # Strip a trailing ? if it exists 120 if (req.url ~ "?$") { 121 set req.url = regsub(req.url, "?$", ""); 122 } 20
  • 21. 124 # Some generic cookie manipulation, useful for all templates that follow 125 # Remove the "has_js" cookie 126 set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", ""); 127 128 # Remove any Google Analytics based cookies 129 set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", ""); 130 set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", ""); 131 set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", ""); 132 set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", ""); 133 set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", ""); 134 135 # Remove the Quant Capital cookies (added by some plugin, all __qca) 136 set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", ""); 137 138 # Remove the AddThis cookies 139 set req.http.Cookie = regsuball(req.http.Cookie, "__atuvc=[^;]+(; )?", ""); 140 141 # Remove a ";" prefix in the cookie if present 142 set req.http.Cookie = regsuball(req.http.Cookie, "^;s*", ""); 143 144 # Are there cookies left with only spaces or that are empty? 145 if (req.http.cookie ~ "^s*$") { 146 unset req.http.cookie; 147 } 21
  • 22. 149 # Normalize Accept-Encoding header 150 # straight from the manual: https://www.varnish-cache.org/docs/3.0/tutorial/vary.html 151 # TODO: Test if it's still needed, Varnish 4 now does this by itself if http_gzip_support = on 152 # https://www.varnish-cache.org/docs/trunk/users-guide/compression.html 153 # https://www.varnish-cache.org/docs/trunk/phk/gzip.html 154 if (req.http.Accept-Encoding) { 155 if (req.url ~ ".(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { 156 # No point in compressing these 157 unset req.http.Accept-Encoding; 158 } elsif (req.http.Accept-Encoding ~ "gzip") { 159 set req.http.Accept-Encoding = "gzip"; 160 } elsif (req.http.Accept-Encoding ~ "deflate") { 161 set req.http.Accept-Encoding = "deflate"; 162 } else { 163 # unkown algorithm 164 unset req.http.Accept-Encoding; 165 } 166 } 167 168 if (req.http.Cache-Control ~ "(?i)no-cache") { 169 #if (req.http.Cache-Control ~ "(?i)no-cache" && client.ip ~ editors) { # create the acl editors if you want to restrict the Ctrl-F5 170 # http://varnish.projects.linpro.no/wiki/VCLExampleEnableForceRefresh 171 # Ignore requests via proxy caches and badly behaved crawlers 172 # like msnbot that send no-cache with every request. 173 if (! (req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) { 174 #set req.hash_always_miss = true; # Doesn't seems to refresh the object in the cache 175 return(purge); # Couple this with restart in vcl_purge and X-Purge header to avoid loops 176 } 177 } 22
  • 23. 179 # Large static files are delivered directly to the end-user without 180 # waiting for Varnish to fully read the file first. 181 # Varnish 4 fully supports Streaming, so set do_stream in vcl_backend_response() 182 if (req.url ~ "^[^?]*.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av]) (?.*)?$") { 183 unset req.http.Cookie; 184 return (hash); 185 } 186 187 # Remove all cookies for static files 188 # A valid discussion could be held on this line: do you really need to cache static files that don't cause load? Only if you have memory left. 189 # Sure, there's disk I/O, but chances are your OS will already have these files in their buffers (thus memory). 190 # Before you blindly enable this, have a read here: http://mattiasgeniar. be/2012/11/28/stop-caching-static-files/ 191 if (req.url ~ "^[^?]*. (bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|pdf|png|rtf|swf|txt|woff|xml)(?.*)?$") { 192 unset req.http.Cookie; 193 return (hash); 194 } 195 196 # Send Surrogate-Capability headers to announce ESI support to backend 197 set req.http.Surrogate-Capability = "key=ESI/1.0"; 198 199 if (req.http.Authorization) { 200 # Not cacheable by default 201 return (pass); 202 } 203 204 return (hash); 205 } 23
  • 24. 207 sub vcl_pipe { 208 # Called upon entering pipe mode. In this mode, the request is passed on to the backend, and any further data from both the client and backend is passed on unaltered until either end closes the connection. Basically, Varnish will degrade into a simple TCP proxy, shuffling bytes back and forth. For a connection in pipe mode, no other VCL subroutine will ever get called after vcl_pipe. 209 210 # Note that only the first request to the backend will have 211 # X-Forwarded-For set. If you use X-Forwarded-For and want to 212 # have it set for all requests, make sure to have: 213 # set bereq.http.connection = "close"; 214 # here. It is not set by default as it might break some broken web 215 # applications, like IIS with NTLM authentication. 216 217 #set bereq.http.Connection = "Close"; 218 219 # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example- websockets.html) 220 if (req.http.upgrade) { 221 set bereq.http.upgrade = req.http.upgrade; 222 } 223 224 return (pipe); 225 } 226 227 sub vcl_pass { 228 # Called upon entering pass mode. In this mode, the request is passed on to the backend, and the backend's response is passed on to the client, but is not entered into the cache. Subsequent requests submitted over the same client connection are handled normally. 229 230 # return (pass); 231 } 24
  • 25. 233 # The data on which the hashing will take place 234 sub vcl_hash { 235 # Called after vcl_recv to create a hash value for the request. This is used as a key to look up the object in Varnish. 236 237 hash_data(req.url); 238 239 if (req.http.host) { 240 hash_data(req.http.host); 241 } else { 242 hash_data(server.ip); 243 } 244 245 # hash cookies for requests that have them 246 if (req.http.Cookie) { 247 hash_data(req.http.Cookie); 248 } 249 } 250 251 sub vcl_hit { 252 # Called when a cache lookup is successful. 253 254 if (obj.ttl >= 0s) { 255 # A pure unadultered hit, deliver it 256 return (deliver); 257 } 25
  • 26. 259 # https://www.varnish-cache.org/docs/trunk/users-guide/vcl-grace.html 260 # When several clients are requesting the same page Varnish will send one request to the backend and place the others on hold while fetching one copy from the backend. In some products this is called request coalescing and Varnish does this automatically. 261 # If you are serving thousands of hits per second the queue of waiting requests can get huge. There are two potential problems - one is a thundering herd problem - suddenly releasing a thousand threads to serve content might send the load sky high. Secondly - nobody likes to wait. To deal with this we can instruct Varnish to keep the objects in cache beyond their TTL and to serve the waiting requests somewhat stale content. 262 269 # We have no fresh fish. Lets look at the stale ones. 270 if (std.healthy(req.backend_hint)) { 271 # Backend is healthy. Limit age to 10s. 272 if (obj.ttl + 10s > 0s) { 273 #set req.http.grace = "normal(limited)"; 274 return (deliver); 275 } else { 276 # No candidate for grace. Fetch a fresh object. 277 return(fetch); 278 } 279 } else { 280 # backend is sick - use full grace 281 if (obj.ttl + obj.grace > 0s) { 282 #set req.http.grace = "full"; 283 return (deliver); 284 } else { 285 # no graced object. 286 return (fetch); 287 } 288 } 289 290 291 # fetch & deliver once we get the result 292 return (fetch); # Dead code, keep as a safeguard 293 } 26
  • 27. 295 sub vcl_miss { 296 # Called after a cache lookup if the requested document was not found in the cache. Its purpose is to decide whether or not to attempt to retrieve the document from the backend, and which backend to use. 297 298 return (fetch); 299 } 300 301 # Handle the HTTP request coming from our backend 302 sub vcl_backend_response { 303 # Called after the response headers has been successfully retrieved from the backend. 304 305 # Pause ESI request and remove Surrogate-Control header 306 if (beresp.http.Surrogate-Control ~ "ESI/1.0") { 307 unset beresp.http.Surrogate-Control; 308 set beresp.do_esi = true; 309 } 310 311 # Enable cache for all static files 312 # The same argument as the static caches from above: monitor your cache size, if you get data nuked out of it, consider giving up the static file cache. 313 # Before you blindly enable this, have a read here: http://mattiasgeniar. be/2012/11/28/stop-caching-static-files/ 314 if (bereq.url ~ "^[^?]*.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|mp[34] |pdf|png|rar|rtf|swf|tar|tgz|txt|wav|woff|xml|zip)(?.*)?$") { 315 unset beresp.http.set-cookie; 316 } 27
  • 28. 319 # Large static files are delivered directly to the end-user without 320 # waiting for Varnish to fully read the file first. 321 # Varnish 4 fully supports Streaming, so use streaming here to avoid locking. 322 if (bereq.url ~ "^[^?]*.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av]) (?.*)?$") { 323 unset beresp.http.set-cookie; 324 set beresp.do_stream = true; # Check memory usage it'll grow in fetch_chunksize blocks (128k by default) if 325 # the backend doesn't send a Content-Length header, so only enable it for big objects 326 set beresp.do_gzip = false; # Don't try to compress it for storage 327 } 329 # Sometimes, a 301 or 302 redirect formed via Apache's mod_rewrite can mess with the HTTP port that is being passed along. 330 # This often happens with simple rewrite rules in a scenario where Varnish runs on :80 and Apache on :8080 on the same box. 331 # A redirect can then often redirect the end-user to a URL on :8080, where it should be : 80. 332 # This may need finetuning on your setup. 333 # 334 # To prevent accidental replace, we only filter the 301/302 redirects for now. 335 if (beresp.status == 301 || beresp.status == 302) { 336 set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", ""); 337 } 339 # Disable queue coalescence for uncacheable objects 340 if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") { 341 set beresp.uncacheable = true; # hit_for_pass 342 set beresp.ttl = 120s; # Remeber this 343 return (deliver); 344 } 346 # Allow stale content, in case the backend goes down. 347 # make Varnish keep all objects for 6 hours beyond their TTL 348 set beresp.grace = 6h; 350 return (deliver); 351 } 28
  • 29. 353 # The routine when we deliver the HTTP request to the user 354 # Last chance to modify headers that are sent to the client 355 sub vcl_deliver { 356 # Called before a cached object is delivered to the client. 357 358 if (obj.hits > 0) { # Add debug header to see if it's a HIT/MISS and the number of hits, disable when not needed 359 set resp.http.X-Cache = "HIT"; 360 } else { 361 set resp.http.X-Cache = "MISS"; 362 } 363 # Please note that obj.hits behaviour changed in 4.0, now it counts per objecthead, not per object 364 # and obj.hits may not be reset in some cases where bans are in use. See bug 1492 for details. 365 # So take hits with a grain of salt 366 set resp.http.X-Cache-Hits = obj.hits; 368 # Remove some headers: PHP version 369 unset resp.http.X-Powered-By; 371 # Remove some headers: Apache version & OS 372 unset resp.http.Server; 373 unset resp.http.X-Drupal-Cache; 374 unset resp.http.X-Varnish; 375 unset resp.http.Via; 376 unset resp.http.Link; 378 return (deliver); 379 } 380 381 sub vcl_purge { 382 # restart request 383 set req.http.X-Purge = "Yes"; 384 return(restart); 385 } 29
  • 30. 387 sub vcl_synth { 388 if (resp.status == 720) { 389 # We use this special error status 720 to force redirects with 301 (permanent) redirects 390 # To use this, call the following from anywhere in vcl_recv: error 720 "http: //host/new.html" 391 set resp.http.Location = resp.reason; 392 set resp.status = 301; 393 return (deliver); 394 } elseif (resp.status == 721) { 395 # And we use error status 721 to force redirects with a 302 (temporary) redirect 396 # To use this, call the following from anywhere in vcl_recv: error 720 "http: //host/new.html" 397 set resp.http.Location = resp.reason; 398 set resp.status = 302; 399 return (deliver); 400 } 401 402 return (deliver); 403 } 404 405 406 sub vcl_fini { 407 # Called when VCL is discarded only after all requests have exited the VCL. Typically used to clean up VMODs. 408 409 return (ok); 410 } 30
  • 31. sub vcl_recv { if (req.url ~ "^/varnish/") { # Lame example to generate content, look down in vcl_synth for status 820 return (synth(820, "Test")); } } sub vcl_synth { if (resp.status == 820) { # Lame example showing how to generate synthetic content. # Usually to do this you would use a vmod from https://www.varnish-cache.org/vmods # to do things like memcache/redis/database/... lookups and return meaningful things # expected url /varnish/parameter1/min/max/ -> /varnish/real_random_api/8/32/ set resp.http.Content-Type = "text/plain; charset=utf-8"; set req.http.X-parameter1 = regsub(req.url, "^/varnish/(.*?)/.*", "1"); set req.http.X-min = regsub(req.url, "^/varnish/.*?/(.*?)/.*", "1"); set req.http.X-max = regsub(req.url, "^/varnish/.*?/.*?/(.*?)/.*", "1"); synthetic("You are " + client.ip + {" url: "} + req.url + {" reason: "} + resp.reason + {" 1st parameter: "} + req.http.X-parameter1 + {" Have your random number between "} + req.http.X-min + " and " + req.http.X-max + " : " + std.random (std.real(req.http.X-min, 0), std.real(req.http.X-max, 100)) + {" End "}); set resp.status = 200; # Be careful to set it after using resp.reason or it'll overwrite it return (deliver); } return (deliver); } 31
  • 32. Playing with vcl_synth $ GET -E http://localhost:8080/varnish/reason/-8/42/ GET http://localhost:8080/varnish/reason/-8/42/ User-Agent: lwp-request/6.03 libwww-perl/6.05 200 OK Connection: close Date: Mon, 24 Nov 2014 15:26:12 GMT Accept-Ranges: bytes Server: Varnish Content-Length: 133 Content-Type: text/plain; charset=utf-8 Client-Date: Mon, 24 Nov 2014 15:26:12 GMT Client-Peer: 127.0.0.1:8080 Client-Response-Num: 1 X-Varnish: 42 You are 127.0.0.1 url: /varnish/reason/-8/42/ reason: Test 1st parameter: reason Have a random number between -8 and 42 : -2.204 End 32
  • 33. But that's not enough: $ GET -e http://test/test1.html 200 OK Connection: close Date: Fri, 03 Oct 2014 16:37:59 GMT Accept-Ranges: bytes ETag: "3d838cc-51-504816b16fe6a" Server: Apache Vary: Accept-Encoding Content-Length: 81 Content-Type: text/html Last-Modified: Fri, 03 Oct 2014 09:32:57 GMT 33
  • 34. But that's not enough: # http://httpd.apache.org/docs/2.0/mod/mod_expires.html ExpiresActive On ExpiresByType image/gif "access plus 4 days" #<FilesMatch ".(gif|jpe?g|png)$"> # Header merge Cache-Control "public" # Default anyway # ExpiresDefault "access plus 4 days" #</FilesMatch> ExpiresByType image/jpg "access plus 4 days" ExpiresByType image/jpeg "access plus 4 days" ExpiresByType image/png "access plus 4 days" ExpiresByType image/x-icon "access plus 4 days" ExpiresByType text/css "access plus 3 days" ExpiresByType application/x-javascript "access plus 3 days" ExpiresByType text/html "access plus 4 hours" ExpiresByType application/xml "access plus 1 hours" 34
  • 35. But that's not enough: $ GET -e http://test/test1.html 200 OK Cache-Control: max-age=14400 Connection: close Date: Fri, 03 Oct 2014 17:37:42 GMT Accept-Ranges: bytes ETag: "3d838cc-51-504816b16fe6a" Server: Apache Vary: Accept-Encoding Content-Length: 81 Content-Type: text/html Expires: Fri, 03 Oct 2014 21:37:42 GMT Last-Modified: Fri, 03 Oct 2014 09:32:57 GMT 35
  • 36. Numbers on faster hardware (AMD FX(tm)-8120 Eight-Core Processor 32GB RAM) /usr/sbin/ab2 -n 500000 -c 200 -k -H "Accept-encoding: gzip" "http: //localhost/prueba.html" Requests per second: 24318.71 [#/sec] (mean) Time per request: 8.224 [ms] (mean) Time per request: 0.041 [ms] (mean, across all concurrent requests) Transfer rate: 8161.06 [Kbytes/sec] received /usr/sbin/ab2 -n 500000 -c 200 -k -H "Accept-encoding: gzip" "http: //localhost:8080/prueba.html" Requests per second: 25780.13 [#/sec] (mean) Time per request: 7.758 [ms] (mean) Time per request: 0.039 [ms] (mean, across all concurrent requests) Transfer rate: 8611.04 [Kbytes/sec] received 36
  • 37. Resources ● https://www.varnish-cache.org/docs ○ https://www.varnish-software.com/static/book/VCL_Basics.html ○ https://www.varnish-cache.org/trac/wiki ● High Performance Browser Networking by Ilya Grigorik (http: //chimera.labs.oreilly.com/books/1230000000545/index.html) ● Caching in HTTP (http://www.w3.org/Protocols/rfc2616/rfc2616- sec13.html) ● The only moment you should ever cache static files is if you have memory to spare (http://mattiasgeniar.be/2012/11/28/stop-caching-static- files/) ● How to Use Varnish to Speed up my Website (http://symfony. com/doc/current/cookbook/cache/varnish.html) ● https://www.varnish-cache.org/vmods (redis, memcache, MySQL, PostgreSQL, ratelimit, device detection, json, auth, ...) 37