SlideShare a Scribd company logo
1 of 58
Download to read offline
Varnish @ Opera 
v3 / DevOps Norway Meetup 
Oslo, 17th September 2014 
Cosimo Streppone <cosimo@opera.com>
1st Varnish deployment: My Opera 
• October 2009 
• 1 old recycled machine, 2 Gb of disk allocated 
• Started serving static pictures (1M+ req/day) 
• Then more... 
• Even more... 
• ... 
• ~15% of all My Opera requests were «varnished» 
• Around 8M req/day
My Opera – The start 
• Still using Debian Etch 
First Varnish instance was running v1.x from Etch. 
several years old, not good 
• Experienced VIPs 
– ”Very Interesting Problems” 
– User X getting User Y's session 
– Random users getting admin powers. Nightmare! 
• Theory: Varnish was caching response bodies that contained 
Set-Cookie: opera_session=<session_id>
My Opera – The start 
if (req.url ~ "^/community/users/avatar.pl/[0-9]+$" 
|| req.url ~ "^/.+/avatar.pl$" 
|| req.url ~ "^/.+/picture.pl?xscale=100$" 
|| req.url ~ "^/desktopteam/xml/atom/blog/?$" 
|| req.url ~ "^/desktopteam/xml/rss/blog/?$" 
|| req.url ~ "^/community/api/users/friends.pl?user=.+$" 
|| req.url ~ "^/community/api/users/groups.pl?user=.+$" 
) { 
unset req.http.Cookie; 
unset req.http.Authorization; 
lookup; 
}
My Opera – Pass logged in users 
... 
# Check for cookie only after always-cache URLs 
if (req.http.Cookie ~ "(opera_session|opera_persistent_)") { 
pass; 
} 
# DANGER, Will Robinson! Caching the front-page 
# At this point, lots of Google Analytics cookies will go in. 
# No problem. It's stuff used by Javascript 
if (req.url ~ "^/community/$") { 
lookup; 
} 
pass; 
}
My Opera: testing Varnish setup 
... 
ok 289 - Got response from backend for /community/ (from ...) 
ok 290 - Correct status line 
# Adding header [Cookie] => [language=it] 
# ---------- 
# GET http://cache01.my.opera.com:6081/community/ 
# Host: my.opera.com 
# ------------ 
ok 291 - 2nd request: got response from backend for /community/ (from...) 
ok 292 - Correct status line 
# X-Varnish: 1211283813 1211283812 
# X-Varnish-Status: hit 
# X-Varnish-Cacheable: yes, language cookie 
# X-Varnish-URL: /community/ 
ok 293 - URL '/community/' was handled correctly by varnish 
# cookie_header: 
ok 294 - URL '/community/' has correct cookies (or no cookies) 
1..294 
X-Varnish: 1211283813 1211283812 
X-Varnish-Status: hit 
X-Varnish-Cacheable: yes, language cookie 
X-Varnish-URL: /community/ 
All tests successful.
My Opera – Next steps
My Opera – Next steps 
● Front page caching 
● Static assets and UGC 
● On-the-fly thumbnails 
● “Shields-up” configuration
Front page caching 
Problem 
• Very dynamic, i18n 
• Accept-Language 
header variation 
• Vary: Accept- 
Language sub-optimal 
Solution 
• varnish-accept-language 
“extension”
Front page caching - Accept-Language 
SUPPORTED_LANGUAGES = “:de:es:it:ru:” 
DEFAULT_LANGUAGE = “en” 
Client sends 
Accept-Language: ru, uk;q=0.9 
Accept-Language: es-ES, es;q=0.8 
Accept-Language: fr, it;q=0.7 
Accept-Language: fr 
Backend receives 
Accept-Language: ru 
Accept-Language: es 
Accept-Language: it 
Accept-Language: ben
Front page caching
Static assets and UGC servers 
Problem 
• One central location 
• SPOF 
• High latency US -> NO 
Solution 
• Decentralized varnish 
servers in multiple DC 
• Talking to 1 backend 
• Very long TTL 
• Health probes 
• Cache invalidation API 
• Built our GeoDNS
Thumbnail generation and caching 
Problem 
• Change of Design™ 
made our millions of 
pre-generated 
thumbnails useless 
Solution 
• Switch to on-the-fly 
generation model 
• Used mod_dims (AOL) 
• Varnish on :80 
• 2 backends 
300k objects 
95% hit rate avg 
800 req/s/backend peak
Thumbnail generation and caching 
How it works 
http://localhost/dims/ 
crop/472x360/ 
contrast/+1/ 
quality/90/ 
/actual/picture/url.jpg (remote too!) 
Using rewrite rules 
Http://localhost/tn/small/ 
/actual/picture/url.jpg
Thumbnail generation and caching 
● Recognize mobile/non-mobile 
● Scale thumbnails on the fly 
● Reduce JPEG quality 
Ex.: /thumb/small/quality/80/some/path/pic.jpg
Shields-up configuration 
Problem 
• Original setup too 
specific to My Opera 
• Long tail of non-popular 
content 
“unprotected” 
• Can we find some 
more generic setup? 
Solution 
• DDoS 
• Varnish in front, rather 
than after frontends 
• Cache most logged out 
requests with lower TTL 
• Compromise solution, 
but generic enough
Other projects
Other projects 
Many since then! 
• Sitecheck 
• Opera.com 
• TV Store 
• Speeddials 
• Discover 
• ...
Opera Discover 
My current project 
80M backend API requests/day 
260M image requests/day
GeoIP country check
Country-level ban 
• Contract mandates that TV Store shouldn't 
be available in specific countries 
• Country check in the backend means no 
caching is possible 
• Implemented with varnish-geoip 
https://github.com/cosimo/varnish-geoip
https://github.com/cosimo/varnish-geoip
Country-level ban 
sub country_ban_list_check { 
# Allow testing of country ban 
if (req.http.Cookie ~ "x_geo_ip_forceds*=s*country:..") { 
set req.http.X-Geo-IP = regsuball( 
req.http.Cookie, 
"^.*x_geo_ip_forceds*=s*(country:..).*$", "1" 
); 
log "Forced X-Geo-IP to '" req.http.X-Geo-IP "'"; 
} 
# Block access to tvstore in these countries 
if (req.http.X-Geo-IP && 
req.http.X-Geo-IP ~ "^country:(C1|C2|C3|...)$") { 
log "Country ban"; 
error 750 "tvstore is not available in your country"; 
} 
} 
sub vcl_recv { 
C{ vcl_geoip_country_set_header_xff(sp); }C 
call country_ban_list_check; 
}
VCL library
accept-encoding.vcl (now obsolete) 
# STD: Deal with different Accept-Encoding formats 
sub accept_encoding_normalize { 
if (req.http.Accept-Encoding) { 
if (req.http.Accept-Encoding ~ "gzip") { 
set req.http.Accept-Encoding = "gzip"; 
} 
elsif (req.http.Accept-Encoding ~ "deflate") { 
set req.http.Accept-Encoding = "deflate"; 
} 
else { 
unset req.http.Accept-Encoding; 
} 
} 
}
accept-language.vcl 
C{ 
/* 
* Accept-language header normalization 
* 
* - Parses client Accept-Language HTTP header 
* - Tries to find the best match with the supported languages 
* - Writes the best match as req.http.X-Varnish-Accept-Language 
* 
* http://github.com/cosimo/varnish-accept-language 
*/ 
#include <ctype.h> /* isupper */ 
#include <stdio.h> 
#include <stdlib.h> /* qsort */ 
#include <string.h> 
#define DEFAULT_LANGUAGE "en" 
#define SUPPORTED_LANGUAGES ":de:en:es-la:fr:fy:hu:ja:no:pl:pt-br: 
ru:sk:sq:sr:tr:uk:vn:xx-lol:zh-tw:" 
…
maintenance.vcl + {up,down}.sh 
include "/etc/varnish/accept-encoding.vcl"; 
backend oopsy { 
.host = "10.20.21.22”; 
.port = "80"; 
} 
sub vcl_recv { 
set req.backend = oopsy; 
# Serve page from within Varnish. See vcl_error() 
if (req.url == "/ping.html") { 
error 700; 
} 
call accept_encoding_normalize; 
# Collapse URLs, so that we have just one cached object 
set req.url = "/maintenance-down"; 
remove req.http.Cookie; 
remove req.http.Authorization; 
return (lookup); 
}
purge.vcl 
acl purge { … } 
sub vcl_recv { 
if (req.request == "PURGE") { 
If (! (client.ip ~ purge)) { 
error 405 "Not allowed."; 
} 
purge("req.url == " req.url); 
error 200 "Purged."; 
} 
else if (req.request == "PURGE_SUFFIX") { 
set req.http.X-URL = 
regsuball(req.url, "[|]|[^.$|()*+?{}]", "0") "$"; 
purge_url(req.http.X-URL); 
unset req.http.X-URL; 
error 200 "Purged suffix."; 
} 
else if (req.request == "PURGE_PREFIX") { 
… 
} 
} 
Ugly!
X-forwarded-for.vcl 
# See http://www.varnish-cache.org/trac/ticket/540 
sub inject_forwarded_for { 
# Rename the incoming XFF header to work around a Varnish bug 
if (req.http.X-Forwarded-For) { 
# Append the client IP 
set req.http.X-Real-Forwarded-For = 
req.http.X-Forwarded-For ", " 
regsub(client.ip, ":.*", ""); 
} 
else { 
# Simply use the client IP 
set req.http.X-Real-Forwarded-For = regsub(client.ip, 
":.*", ""); 
} 
} 
Wat!?
Testing VCLs – http-cuke
http-cuke – csrf.test 
Feature: Site uses cookies to protect against CSRF attacks 
In order to protect the users from CSRF attacks 
As a web site developer 
I want to verify that some pages send out a CSRF cookie token to 
the browser or device 
Scenario: Accessing the Backgammon application URL 
Given a "OPR/24.0.1558.23 (Linux … Opera)" user agent 
When I go to "https://server/store/app/backgammon" 
Then the final HTTP status code should be "200" 
And the page should contain "A board game for one player" 
And the page should not be cached by varnish 
And the server should send a CSRF token
http-cuke – prove-like output 
$ http-cuke --test ./csrf.test 
$ http-cuke --test-dir ./some-dir
http-cuke – a sample test run 
# ============================================================ 
# FEATURE: Web site uses cookies to protect against CSRF attacks 
# ============================================================ 
# ------------------------------------------------------------ 
# SCENARIO: Accessing the Backgammon application URL 
# ------------------------------------------------------------ 
ok 1 - Given a "OPR/24... (Linux...)" user agent 
ok 2 - When I go to "https://server/app/backgammon" 
ok 3 - Status code is 200 (expected 200) 
ok 4 - Then the final HTTP status code should be "200" 
ok 5 - String 'A board game for one player' was found in the page 
ok 6 - Then the page should contain "A board game for one player" 
ok 7 - X-Varnish header contains only current XID (523289525) 
ok 8 - Age of cached resource is zero 
ok 9 - Then the page should not be cached by varnish 
ok 10 - CSRF token was found (49a0da1b2758bf62a028072e4f7f36dc) 
ok 11 - Then the server should send a CSRF token
https://github.com/cosimo/http-cuke
Dumping varnishlog
vlogdump 
$ varnishlog | vlogdump
vlogdump – a sample test run 
$ varnishlog | vlogdump -v only_misses=1 
172.22.0.15 => GET /assets/tn/m/mq/e85ed...6733a48802 HTTP/1.0 MISS 
<= 200 OK 
172.22.0.18 => GET /assets/icons/.....-technology.png HTTP/1.0 MISS 
<= 304 Not Modified 
$ varnishlog | vlogdump -v show_req_headers=1 
172.22.0.15 => GET /assets/3a626ed......e168914568080 HTTP/1.0 MISS 
<= 200 OK 51.483 ms 
req.http.Host = discovery.opera.com 
req.http.User-Agent = Amazon CloudFront 
req.http.X-Forwarded-For = 11.12.34.56 
req.http.X-Amz-Cf-Id = ...0AZZaPkt87avA== 
req.http.Connection = keep-alive 
...
vlogdump – demo?
https://github.com/cosimo/vlogdump
vlogdump + rtail 
Remote tailing made easy. 
60 lines of Perl. 
$ rtail --host=h1 --host=h2 --host=h3 ...  
--command varnishlog  
| vlogdump
vlogdump + rtail 
No github yet :-)
Puppet module
varnish/manifests/init.pp 
class varnish { 
package { "varnish": ensure => "installed" } 
file { "/etc/init.d/varnish": … } 
file { "/etc/sysctl.conf": … } 
exec { "update-sysctl": … } 
file { "/usr/share/varnish/purge-cache": … } 
service { "varnish": ensure => "running", … } 
munin::plugin::custom { "varnish_": } 
munin::plugin { [ 
"varnish_backend_traffic", 
"varnish_expunge", 
… 
} 
}
Custom init script 
# Lower stack limit demand for every Varnish thread 
# http://projects.linpro.no/pipermail/varnish-misc/2009-August/002977.html 
# Still relevant for Varnish 3 ?? 
ulimit -s 256 
# Startup with custom cc_command fails 
# http://stackoverflow.com/a/8333333 
# Filed Debian bug #659005 
if bash -c "start-stop-daemon  
--start --quiet --pidfile ${PIDFILE}  
--exec ${DAEMON} -- -P ${PIDFILE}  
${DAEMON_OPTS} > ${output} 2>&1"; then 
log_end_msg 0 
else 
…
Custom init script 
# Optionally warm up the cache 
# 
# Drop a custom script into this path 
# to have it being picked up by the 
# main init script. 
if [ -x /usr/share/varnish/cache-warmup ]; then 
/usr/share/varnish/cache-warmup 
fi
Custom sysctl settings 
# From http://varnish.projects.linpro.no/wiki/Performance 
# + our own tweaking and tuning 
net.ipv4.ip_local_port_range = 1024 65536 
net.core.rmem_max = 16777216 
net.core.wmem_max = 16777216 
net.ipv4.tcp_rmem = 4096 87380 16777216 
net.ipv4.tcp_wmem = 4096 65536 16777216 
net.ipv4.tcp_fin_timeout = 30 
net.core.netdev_max_backlog = 30000 
net.ipv4.tcp_no_metrics_save = 1 
net.core.somaxconn = 262144 
net.ipv4.tcp_syncookies = 1 
net.ipv4.tcp_max_orphans = 262144 
net.ipv4.tcp_max_syn_backlog = 262144 
net.ipv4.tcp_synack_retries = 2 
net.ipv4.tcp_syn_retries = 2
Purge cache script 
Modeled after Debian vcl-reload script 
$ purge-cache -a 
$ purge-cache -u http://some.url 
$ purge-cache -r '^/(home|user)/'
Cache warmup script 
Drop-in script in 
/usr/share/varnish/cache-warmup 
Invoked right after startup
varnish/manifests/init.pp – 2 
define varnish::config ( 
$vcl_conf="default.vcl", $listen_address="", 
$listen_port=6081, $thread_min=400, 
$thread_max=5000, $thread_timeout=30, 
$storage_type="malloc", $storage_size="12G", 
$ttl=60, $thread_pools=$processorcount, 
$sess_workspace=131072, $cc_command="", 
$sess_timeout=3 ) { 
file { "/etc/default/varnish": 
ensure => "present", 
owner => "root", 
group => "root", 
mode => 644, 
content => template("varnish/debian-defaults.erb"), 
require => Package["varnish"], 
notify => Service["varnish"], 
} 
}
Example of varnish::config 
varnish::config { 'cache-varnish-config': 
vcl_conf => 'cache.vcl', 
storage_type => 'malloc', 
storage_size => '20G', 
listen_port => 80, 
sess_workspace => 131072, 
ttl => 86400, 
thread_pools => 4, 
thread_min => 800, 
thread_max => 2000, 
# Necessary for GeoIP 
cc_command => 
'exec cc -fpic -shared -Wl,-x  
-L/usr/include/GeoIP.h -lGeoIP -o %o %s', 
}
varnish/manifests/init.pp – 3 
define varnish::vcl ($source) { 
file { "/etc/varnish/${name}.vcl": 
ensure => 'file', 
owner => 'root', 
group => 'root', 
Mode => '0644', 
source => $source, 
require => Package['varnish'], 
notify => Service['varnish'], 
} 
}
https://github.com/cosimo/puppet-modules
Migration to Varnish 3
Following Debian stable 
• Wheezy now ships with 3.0.2 
• 2.0 > 2.1 migration was painless 
• 2.1 > 3.0 migration was painless too
Next steps?
Next Steps? 
• Personalized (but cached) content 
• A/B Testing 
• ESI? 
• VMods? 
• Migration to V4
Spørsmål?
Takk!

More Related Content

What's hot

PuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with PuppetPuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with PuppetWalter Heck
 
Testing your infrastructure with litmus
Testing your infrastructure with litmusTesting your infrastructure with litmus
Testing your infrastructure with litmusBram Vogelaar
 
My Opera meets Varnish, Dec 2009
My Opera meets Varnish, Dec 2009My Opera meets Varnish, Dec 2009
My Opera meets Varnish, Dec 2009Cosimo Streppone
 
More tips n tricks
More tips n tricksMore tips n tricks
More tips n tricksbcoca
 
Making Your Capistrano Recipe Book
Making Your Capistrano Recipe BookMaking Your Capistrano Recipe Book
Making Your Capistrano Recipe BookTim Riley
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStackBram Vogelaar
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)Soshi Nemoto
 
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...Willian Molinari
 
Hacking ansible
Hacking ansibleHacking ansible
Hacking ansiblebcoca
 
Ansible : what's ansible & use case by REX
Ansible :  what's ansible & use case by REXAnsible :  what's ansible & use case by REX
Ansible : what's ansible & use case by REXSaewoong Lee
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stackBram Vogelaar
 
How to Develop Puppet Modules: From Source to the Forge With Zero Clicks
How to Develop Puppet Modules: From Source to the Forge With Zero ClicksHow to Develop Puppet Modules: From Source to the Forge With Zero Clicks
How to Develop Puppet Modules: From Source to the Forge With Zero ClicksCarlos Sanchez
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetWalter Heck
 
Creating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesCreating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesBram Vogelaar
 
Ansible for beginners
Ansible for beginnersAnsible for beginners
Ansible for beginnersKuo-Le Mei
 
DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)Soshi Nemoto
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteBram Vogelaar
 

What's hot (20)

PuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with PuppetPuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with Puppet
 
Testing your infrastructure with litmus
Testing your infrastructure with litmusTesting your infrastructure with litmus
Testing your infrastructure with litmus
 
My Opera meets Varnish, Dec 2009
My Opera meets Varnish, Dec 2009My Opera meets Varnish, Dec 2009
My Opera meets Varnish, Dec 2009
 
More tips n tricks
More tips n tricksMore tips n tricks
More tips n tricks
 
Making Your Capistrano Recipe Book
Making Your Capistrano Recipe BookMaking Your Capistrano Recipe Book
Making Your Capistrano Recipe Book
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)
 
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
 
Hacking ansible
Hacking ansibleHacking ansible
Hacking ansible
 
Ansible : what's ansible & use case by REX
Ansible :  what's ansible & use case by REXAnsible :  what's ansible & use case by REX
Ansible : what's ansible & use case by REX
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
 
How to Develop Puppet Modules: From Source to the Forge With Zero Clicks
How to Develop Puppet Modules: From Source to the Forge With Zero ClicksHow to Develop Puppet Modules: From Source to the Forge With Zero Clicks
How to Develop Puppet Modules: From Source to the Forge With Zero Clicks
 
kubernetes practice
kubernetes practicekubernetes practice
kubernetes practice
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of Puppet
 
Creating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesCreating Reusable Puppet Profiles
Creating Reusable Puppet Profiles
 
Ansible for beginners
Ansible for beginnersAnsible for beginners
Ansible for beginners
 
DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)
 
Puppet fundamentals
Puppet fundamentalsPuppet fundamentals
Puppet fundamentals
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suite
 

Similar to How we use and deploy Varnish at Opera

Varnish: Making eZ Publish sites fly
Varnish: Making eZ Publish sites flyVarnish: Making eZ Publish sites fly
Varnish: Making eZ Publish sites flyPeter Keung
 
HTTP Caching and PHP
HTTP Caching and PHPHTTP Caching and PHP
HTTP Caching and PHPDavid de Boer
 
DVWA BruCON Workshop
DVWA BruCON WorkshopDVWA BruCON Workshop
DVWA BruCON Workshoptestuser1223
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统yiditushe
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesLindsay Holmwood
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebookguoqing75
 
Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)Ben Hall
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
Wordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccionWordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccionSysdig
 
How to create your own hack environment
How to create your own hack environmentHow to create your own hack environment
How to create your own hack environmentSumedt Jitpukdebodin
 
Express Presentation
Express PresentationExpress Presentation
Express Presentationaaronheckmann
 
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
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hopeMarcus Ramberg
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabricandymccurdy
 
Reverse proxies & Inconsistency
Reverse proxies & InconsistencyReverse proxies & Inconsistency
Reverse proxies & InconsistencyGreenD0g
 

Similar to How we use and deploy Varnish at Opera (20)

Varnish: Making eZ Publish sites fly
Varnish: Making eZ Publish sites flyVarnish: Making eZ Publish sites fly
Varnish: Making eZ Publish sites fly
 
HTTP Caching and PHP
HTTP Caching and PHPHTTP Caching and PHP
HTTP Caching and PHP
 
infra-as-code
infra-as-codeinfra-as-code
infra-as-code
 
DVWA BruCON Workshop
DVWA BruCON WorkshopDVWA BruCON Workshop
DVWA BruCON Workshop
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统
 
Write php deploy everywhere
Write php deploy everywhereWrite php deploy everywhere
Write php deploy everywhere
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook
 
Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Wordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccionWordpress y Docker, de desarrollo a produccion
Wordpress y Docker, de desarrollo a produccion
 
How to create your own hack environment
How to create your own hack environmentHow to create your own hack environment
How to create your own hack environment
 
Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
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
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hope
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabric
 
Pecl Picks
Pecl PicksPecl Picks
Pecl Picks
 
EC2
EC2EC2
EC2
 
Reverse proxies & Inconsistency
Reverse proxies & InconsistencyReverse proxies & Inconsistency
Reverse proxies & Inconsistency
 

More from Cosimo Streppone

Velocity 2012 - Learning WebOps the Hard Way
Velocity 2012 - Learning WebOps the Hard WayVelocity 2012 - Learning WebOps the Hard Way
Velocity 2012 - Learning WebOps the Hard WayCosimo Streppone
 
Velocity 2011 - Our first DDoS attack
Velocity 2011 - Our first DDoS attackVelocity 2011 - Our first DDoS attack
Velocity 2011 - Our first DDoS attackCosimo Streppone
 
Mojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tMojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tCosimo Streppone
 
Surge 2010 - from disaster to stability - scaling my.opera.com
Surge 2010 - from disaster to stability - scaling my.opera.comSurge 2010 - from disaster to stability - scaling my.opera.com
Surge 2010 - from disaster to stability - scaling my.opera.comCosimo Streppone
 
YAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses PerlYAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses PerlCosimo Streppone
 
NPW2009 - my.opera.com scalability v2.0
NPW2009 - my.opera.com scalability v2.0NPW2009 - my.opera.com scalability v2.0
NPW2009 - my.opera.com scalability v2.0Cosimo Streppone
 
IPW2008 - my.opera.com scalability
IPW2008 - my.opera.com scalabilityIPW2008 - my.opera.com scalability
IPW2008 - my.opera.com scalabilityCosimo Streppone
 

More from Cosimo Streppone (8)

Velocity 2012 - Learning WebOps the Hard Way
Velocity 2012 - Learning WebOps the Hard WayVelocity 2012 - Learning WebOps the Hard Way
Velocity 2012 - Learning WebOps the Hard Way
 
Italian, do you speak it?
Italian, do you speak it?Italian, do you speak it?
Italian, do you speak it?
 
Velocity 2011 - Our first DDoS attack
Velocity 2011 - Our first DDoS attackVelocity 2011 - Our first DDoS attack
Velocity 2011 - Our first DDoS attack
 
Mojolicious: what works and what doesn't
Mojolicious: what works and what doesn'tMojolicious: what works and what doesn't
Mojolicious: what works and what doesn't
 
Surge 2010 - from disaster to stability - scaling my.opera.com
Surge 2010 - from disaster to stability - scaling my.opera.comSurge 2010 - from disaster to stability - scaling my.opera.com
Surge 2010 - from disaster to stability - scaling my.opera.com
 
YAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses PerlYAPC::EU::2009 - How Opera Software uses Perl
YAPC::EU::2009 - How Opera Software uses Perl
 
NPW2009 - my.opera.com scalability v2.0
NPW2009 - my.opera.com scalability v2.0NPW2009 - my.opera.com scalability v2.0
NPW2009 - my.opera.com scalability v2.0
 
IPW2008 - my.opera.com scalability
IPW2008 - my.opera.com scalabilityIPW2008 - my.opera.com scalability
IPW2008 - my.opera.com scalability
 

Recently uploaded

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
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
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
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROmotivationalword821
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
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
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
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
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 

Recently uploaded (20)

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...
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
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
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTRO
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
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
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
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)
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 

How we use and deploy Varnish at Opera

  • 1. Varnish @ Opera v3 / DevOps Norway Meetup Oslo, 17th September 2014 Cosimo Streppone <cosimo@opera.com>
  • 2. 1st Varnish deployment: My Opera • October 2009 • 1 old recycled machine, 2 Gb of disk allocated • Started serving static pictures (1M+ req/day) • Then more... • Even more... • ... • ~15% of all My Opera requests were «varnished» • Around 8M req/day
  • 3. My Opera – The start • Still using Debian Etch First Varnish instance was running v1.x from Etch. several years old, not good • Experienced VIPs – ”Very Interesting Problems” – User X getting User Y's session – Random users getting admin powers. Nightmare! • Theory: Varnish was caching response bodies that contained Set-Cookie: opera_session=<session_id>
  • 4. My Opera – The start if (req.url ~ "^/community/users/avatar.pl/[0-9]+$" || req.url ~ "^/.+/avatar.pl$" || req.url ~ "^/.+/picture.pl?xscale=100$" || req.url ~ "^/desktopteam/xml/atom/blog/?$" || req.url ~ "^/desktopteam/xml/rss/blog/?$" || req.url ~ "^/community/api/users/friends.pl?user=.+$" || req.url ~ "^/community/api/users/groups.pl?user=.+$" ) { unset req.http.Cookie; unset req.http.Authorization; lookup; }
  • 5. My Opera – Pass logged in users ... # Check for cookie only after always-cache URLs if (req.http.Cookie ~ "(opera_session|opera_persistent_)") { pass; } # DANGER, Will Robinson! Caching the front-page # At this point, lots of Google Analytics cookies will go in. # No problem. It's stuff used by Javascript if (req.url ~ "^/community/$") { lookup; } pass; }
  • 6. My Opera: testing Varnish setup ... ok 289 - Got response from backend for /community/ (from ...) ok 290 - Correct status line # Adding header [Cookie] => [language=it] # ---------- # GET http://cache01.my.opera.com:6081/community/ # Host: my.opera.com # ------------ ok 291 - 2nd request: got response from backend for /community/ (from...) ok 292 - Correct status line # X-Varnish: 1211283813 1211283812 # X-Varnish-Status: hit # X-Varnish-Cacheable: yes, language cookie # X-Varnish-URL: /community/ ok 293 - URL '/community/' was handled correctly by varnish # cookie_header: ok 294 - URL '/community/' has correct cookies (or no cookies) 1..294 X-Varnish: 1211283813 1211283812 X-Varnish-Status: hit X-Varnish-Cacheable: yes, language cookie X-Varnish-URL: /community/ All tests successful.
  • 7. My Opera – Next steps
  • 8. My Opera – Next steps ● Front page caching ● Static assets and UGC ● On-the-fly thumbnails ● “Shields-up” configuration
  • 9. Front page caching Problem • Very dynamic, i18n • Accept-Language header variation • Vary: Accept- Language sub-optimal Solution • varnish-accept-language “extension”
  • 10. Front page caching - Accept-Language SUPPORTED_LANGUAGES = “:de:es:it:ru:” DEFAULT_LANGUAGE = “en” Client sends Accept-Language: ru, uk;q=0.9 Accept-Language: es-ES, es;q=0.8 Accept-Language: fr, it;q=0.7 Accept-Language: fr Backend receives Accept-Language: ru Accept-Language: es Accept-Language: it Accept-Language: ben
  • 12. Static assets and UGC servers Problem • One central location • SPOF • High latency US -> NO Solution • Decentralized varnish servers in multiple DC • Talking to 1 backend • Very long TTL • Health probes • Cache invalidation API • Built our GeoDNS
  • 13. Thumbnail generation and caching Problem • Change of Design™ made our millions of pre-generated thumbnails useless Solution • Switch to on-the-fly generation model • Used mod_dims (AOL) • Varnish on :80 • 2 backends 300k objects 95% hit rate avg 800 req/s/backend peak
  • 14. Thumbnail generation and caching How it works http://localhost/dims/ crop/472x360/ contrast/+1/ quality/90/ /actual/picture/url.jpg (remote too!) Using rewrite rules Http://localhost/tn/small/ /actual/picture/url.jpg
  • 15. Thumbnail generation and caching ● Recognize mobile/non-mobile ● Scale thumbnails on the fly ● Reduce JPEG quality Ex.: /thumb/small/quality/80/some/path/pic.jpg
  • 16. Shields-up configuration Problem • Original setup too specific to My Opera • Long tail of non-popular content “unprotected” • Can we find some more generic setup? Solution • DDoS • Varnish in front, rather than after frontends • Cache most logged out requests with lower TTL • Compromise solution, but generic enough
  • 18. Other projects Many since then! • Sitecheck • Opera.com • TV Store • Speeddials • Discover • ...
  • 19. Opera Discover My current project 80M backend API requests/day 260M image requests/day
  • 21. Country-level ban • Contract mandates that TV Store shouldn't be available in specific countries • Country check in the backend means no caching is possible • Implemented with varnish-geoip https://github.com/cosimo/varnish-geoip
  • 23. Country-level ban sub country_ban_list_check { # Allow testing of country ban if (req.http.Cookie ~ "x_geo_ip_forceds*=s*country:..") { set req.http.X-Geo-IP = regsuball( req.http.Cookie, "^.*x_geo_ip_forceds*=s*(country:..).*$", "1" ); log "Forced X-Geo-IP to '" req.http.X-Geo-IP "'"; } # Block access to tvstore in these countries if (req.http.X-Geo-IP && req.http.X-Geo-IP ~ "^country:(C1|C2|C3|...)$") { log "Country ban"; error 750 "tvstore is not available in your country"; } } sub vcl_recv { C{ vcl_geoip_country_set_header_xff(sp); }C call country_ban_list_check; }
  • 25. accept-encoding.vcl (now obsolete) # STD: Deal with different Accept-Encoding formats sub accept_encoding_normalize { if (req.http.Accept-Encoding) { if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } elsif (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; } else { unset req.http.Accept-Encoding; } } }
  • 26. accept-language.vcl C{ /* * Accept-language header normalization * * - Parses client Accept-Language HTTP header * - Tries to find the best match with the supported languages * - Writes the best match as req.http.X-Varnish-Accept-Language * * http://github.com/cosimo/varnish-accept-language */ #include <ctype.h> /* isupper */ #include <stdio.h> #include <stdlib.h> /* qsort */ #include <string.h> #define DEFAULT_LANGUAGE "en" #define SUPPORTED_LANGUAGES ":de:en:es-la:fr:fy:hu:ja:no:pl:pt-br: ru:sk:sq:sr:tr:uk:vn:xx-lol:zh-tw:" …
  • 27. maintenance.vcl + {up,down}.sh include "/etc/varnish/accept-encoding.vcl"; backend oopsy { .host = "10.20.21.22”; .port = "80"; } sub vcl_recv { set req.backend = oopsy; # Serve page from within Varnish. See vcl_error() if (req.url == "/ping.html") { error 700; } call accept_encoding_normalize; # Collapse URLs, so that we have just one cached object set req.url = "/maintenance-down"; remove req.http.Cookie; remove req.http.Authorization; return (lookup); }
  • 28. purge.vcl acl purge { … } sub vcl_recv { if (req.request == "PURGE") { If (! (client.ip ~ purge)) { error 405 "Not allowed."; } purge("req.url == " req.url); error 200 "Purged."; } else if (req.request == "PURGE_SUFFIX") { set req.http.X-URL = regsuball(req.url, "[|]|[^.$|()*+?{}]", "0") "$"; purge_url(req.http.X-URL); unset req.http.X-URL; error 200 "Purged suffix."; } else if (req.request == "PURGE_PREFIX") { … } } Ugly!
  • 29. X-forwarded-for.vcl # See http://www.varnish-cache.org/trac/ticket/540 sub inject_forwarded_for { # Rename the incoming XFF header to work around a Varnish bug if (req.http.X-Forwarded-For) { # Append the client IP set req.http.X-Real-Forwarded-For = req.http.X-Forwarded-For ", " regsub(client.ip, ":.*", ""); } else { # Simply use the client IP set req.http.X-Real-Forwarded-For = regsub(client.ip, ":.*", ""); } } Wat!?
  • 30. Testing VCLs – http-cuke
  • 31. http-cuke – csrf.test Feature: Site uses cookies to protect against CSRF attacks In order to protect the users from CSRF attacks As a web site developer I want to verify that some pages send out a CSRF cookie token to the browser or device Scenario: Accessing the Backgammon application URL Given a "OPR/24.0.1558.23 (Linux … Opera)" user agent When I go to "https://server/store/app/backgammon" Then the final HTTP status code should be "200" And the page should contain "A board game for one player" And the page should not be cached by varnish And the server should send a CSRF token
  • 32. http-cuke – prove-like output $ http-cuke --test ./csrf.test $ http-cuke --test-dir ./some-dir
  • 33. http-cuke – a sample test run # ============================================================ # FEATURE: Web site uses cookies to protect against CSRF attacks # ============================================================ # ------------------------------------------------------------ # SCENARIO: Accessing the Backgammon application URL # ------------------------------------------------------------ ok 1 - Given a "OPR/24... (Linux...)" user agent ok 2 - When I go to "https://server/app/backgammon" ok 3 - Status code is 200 (expected 200) ok 4 - Then the final HTTP status code should be "200" ok 5 - String 'A board game for one player' was found in the page ok 6 - Then the page should contain "A board game for one player" ok 7 - X-Varnish header contains only current XID (523289525) ok 8 - Age of cached resource is zero ok 9 - Then the page should not be cached by varnish ok 10 - CSRF token was found (49a0da1b2758bf62a028072e4f7f36dc) ok 11 - Then the server should send a CSRF token
  • 36. vlogdump $ varnishlog | vlogdump
  • 37. vlogdump – a sample test run $ varnishlog | vlogdump -v only_misses=1 172.22.0.15 => GET /assets/tn/m/mq/e85ed...6733a48802 HTTP/1.0 MISS <= 200 OK 172.22.0.18 => GET /assets/icons/.....-technology.png HTTP/1.0 MISS <= 304 Not Modified $ varnishlog | vlogdump -v show_req_headers=1 172.22.0.15 => GET /assets/3a626ed......e168914568080 HTTP/1.0 MISS <= 200 OK 51.483 ms req.http.Host = discovery.opera.com req.http.User-Agent = Amazon CloudFront req.http.X-Forwarded-For = 11.12.34.56 req.http.X-Amz-Cf-Id = ...0AZZaPkt87avA== req.http.Connection = keep-alive ...
  • 40. vlogdump + rtail Remote tailing made easy. 60 lines of Perl. $ rtail --host=h1 --host=h2 --host=h3 ... --command varnishlog | vlogdump
  • 41. vlogdump + rtail No github yet :-)
  • 43. varnish/manifests/init.pp class varnish { package { "varnish": ensure => "installed" } file { "/etc/init.d/varnish": … } file { "/etc/sysctl.conf": … } exec { "update-sysctl": … } file { "/usr/share/varnish/purge-cache": … } service { "varnish": ensure => "running", … } munin::plugin::custom { "varnish_": } munin::plugin { [ "varnish_backend_traffic", "varnish_expunge", … } }
  • 44. Custom init script # Lower stack limit demand for every Varnish thread # http://projects.linpro.no/pipermail/varnish-misc/2009-August/002977.html # Still relevant for Varnish 3 ?? ulimit -s 256 # Startup with custom cc_command fails # http://stackoverflow.com/a/8333333 # Filed Debian bug #659005 if bash -c "start-stop-daemon --start --quiet --pidfile ${PIDFILE} --exec ${DAEMON} -- -P ${PIDFILE} ${DAEMON_OPTS} > ${output} 2>&1"; then log_end_msg 0 else …
  • 45. Custom init script # Optionally warm up the cache # # Drop a custom script into this path # to have it being picked up by the # main init script. if [ -x /usr/share/varnish/cache-warmup ]; then /usr/share/varnish/cache-warmup fi
  • 46. Custom sysctl settings # From http://varnish.projects.linpro.no/wiki/Performance # + our own tweaking and tuning net.ipv4.ip_local_port_range = 1024 65536 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.ipv4.tcp_fin_timeout = 30 net.core.netdev_max_backlog = 30000 net.ipv4.tcp_no_metrics_save = 1 net.core.somaxconn = 262144 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2
  • 47. Purge cache script Modeled after Debian vcl-reload script $ purge-cache -a $ purge-cache -u http://some.url $ purge-cache -r '^/(home|user)/'
  • 48. Cache warmup script Drop-in script in /usr/share/varnish/cache-warmup Invoked right after startup
  • 49. varnish/manifests/init.pp – 2 define varnish::config ( $vcl_conf="default.vcl", $listen_address="", $listen_port=6081, $thread_min=400, $thread_max=5000, $thread_timeout=30, $storage_type="malloc", $storage_size="12G", $ttl=60, $thread_pools=$processorcount, $sess_workspace=131072, $cc_command="", $sess_timeout=3 ) { file { "/etc/default/varnish": ensure => "present", owner => "root", group => "root", mode => 644, content => template("varnish/debian-defaults.erb"), require => Package["varnish"], notify => Service["varnish"], } }
  • 50. Example of varnish::config varnish::config { 'cache-varnish-config': vcl_conf => 'cache.vcl', storage_type => 'malloc', storage_size => '20G', listen_port => 80, sess_workspace => 131072, ttl => 86400, thread_pools => 4, thread_min => 800, thread_max => 2000, # Necessary for GeoIP cc_command => 'exec cc -fpic -shared -Wl,-x -L/usr/include/GeoIP.h -lGeoIP -o %o %s', }
  • 51. varnish/manifests/init.pp – 3 define varnish::vcl ($source) { file { "/etc/varnish/${name}.vcl": ensure => 'file', owner => 'root', group => 'root', Mode => '0644', source => $source, require => Package['varnish'], notify => Service['varnish'], } }
  • 54. Following Debian stable • Wheezy now ships with 3.0.2 • 2.0 > 2.1 migration was painless • 2.1 > 3.0 migration was painless too
  • 56. Next Steps? • Personalized (but cached) content • A/B Testing • ESI? • VMods? • Migration to V4
  • 58. Takk!