Planet Varnish

May 16, 2013

Hrafnhildur SmaradottirA speedier website at a smaller cost and how Wetpaint uses Varnish to scale

Tony Flint leads the team that owns the happiness and health of the web infrastructure at Wetpaint.com. During our chat with Tony he shared with us his team's relief when they came across Varnish and they could rest assured that their website was up and running irrelevant of peaks in traffic.

May 15, 2013

Per BuerGetting live statistics from Varnish with HLS/HDS

The latter years we’ve seen a surge in the use of HTTP based transports for online video. HTTP Live Streaming (HLS), HTTP Dynamic Streaming (HDS) and Silverlight video (Smooth streaming) are seeing quite a bit of usage. These streaming standards are more or less made for caching. However, due to the stateless nature of the HTTP protocol there is a gap between the streams themselves and the underlying traffic. This makes it hard to get proper insight into what is actually going on in the video distribution system.

April 23, 2013

Ruben RomeroFlying without turbines: Compiler-less Varnish Cache

Varnish Cache uses the gcc compiler by default. If you need it to run without the compiler, for whatever reason, we can provide you with a version of Varnish that does not have that requirement.

April 19, 2013

Hrafnhildur SmaradottirVarnish Administration Course in London, May 2nd and 3rd

Are you using Varnish already but feel you need to learn some tips and tricks? Or do you feel that you need some additional Varnish Configuration Language skills?

April 17, 2013

Per BuerPaywall challenges

When implementing a Paywall in an organization there are a lots of changes needed. There are editorial changes, marketing aspects, tech support and much more. I can’t say I know much about the editorial changes a newspaper must go through when implementing a paid-content strategy, but we’ve been part of quite a few technical teams setting up the logic for paid-content and we’ve learned a few lessons I’d like to share.

Per BuerWithstanding DDOS attacks with Varnish and COTS hardware

Recent years denial of service attacks have become commonplace. You no longer have to create your own botnet in order to attack someone. A Paypal account, some googling skills, a couple of forum posts you can have a 400.000 PPS SYN Flood going in an hour or so.

April 15, 2013

Ruben RomeroVarnish User Group Meeting 7 in NYC #VUG7

We are gearing up for the 7th Varnish User Group Meeting on May 30th-31st 2013 in New York City, USA co-sponsored by Vimeo, 10gen and Varnish Software. The Varnish Administration Course will be held on June 3rd & 4th. Make sure you get a seat by booking it now.

Hrafnhildur SmaradottirVarnish Software acknowledged as one of top 100 private technology ventures in Europe, 2013

Last week, Varnish Software was selected one of the Red Herring Top 100 companies in Europe, 2013. Congratulations to the Varnish team!

March 25, 2013

Hrafnhildur SmaradottirThe evolving paywall terminology

Varnish Software attended the Digital Innovators’ Summit in Berlin last week. We were there to present the Varnish Paywall, our solution for monetizing digital content. People there were interested in what we have to offer and we made some great new contacts there.

Mikko OhtamaaVarnish at the front of WordPress + Apache and Plone CMS virtual hosts

When moving some sites to a new server I upgraded the Varnish cache server configuration serving this setup. Here are my notes how one can use Varnish at the front of virtual hosting.

The setup is following

  • Multiple sites are hosted on the same server. The sites are mix of PHP of Plone sites.
  • Varnish accepts HTTP requests in port 80 and forwards request to the corresponding backend through HTTP proxying
  • Our virtual host rules capture domain names with or without www-prefix, or with any subdomain name prefix
  • Apache runs in non-standard port localhost:81, serving PHP and WordPress. WordPress caching rules are defined in Apache <virtualhost> config file.
  • Every Plone site runs in its own port and process. Plone uses VirtualHostMonster to rewrite publicly facing site URLS. Plone caching HTTP headers are set by plone.app.caching addon.
  • We do extensive cookie sanitization for PHP (generic), WordPress and Plone.  Google Analytics etc. cookies don’t bust the cache and we can still login to WordPress and Plone as admin
  • As a special trick, there is cleaned cookie debugging trick through HTTP response headers

1-IMG_2677

Don’t worry, Varnish can handle little load

 

Pros

  • Blazingly fast, as Varnish is
  • With Plone’s plone.app.caching, one does not need to touch configuration files but Plone caching HTTP headers can be configured through-the-web

Cons

  • Varnish does not have Nginx or Apache style virtual host configuration file facilities by default and making includes is little bit tricky: With many virtualhost the default.vcl config file grows long.
  • Because WordPress cannot do static resource serving as smartly as Plone, which has unique URLs for all static media revisions, you need to purge Varnish manually from command line if you update any static media files like CSS, JS or images.

Varnish /etc/varnish/default.vcl example for Varnish 3.0:

#
# This backend never responds... we get hit in the case of bad virtualhost name
#
backend default {
    .host = "127.0.0.1";
    .port = "55555";
}

backend myplonesite {
    .host = "127.0.0.1";
    .port = "6699";
}

#
# Apache running on server port 81
#
backend apache {
    .host = "127.0.0.1";
    .port = "81";
}

#
# Gues which site / virtualhost we are diving into.
# Apache, Nginx or Plone directly
#
sub choose_backend {

    # WordPress site
    if (req.http.host ~ "^(.*\.)?opensourcehacker\.com(:[0-9]+)?$") {
        set req.backend = apache;
    }

    # Example Plone site
    if (req.http.host ~ "^(.*\.)?myplonesite\.fi(:[0-9]+)?$") {
        set req.backend = myplonesite;

        # Zope VirtualHostMonster
        set req.url = "/VirtualHostBase/http/" + req.http.host + ":80/Plone/VirtualHostRoot" + req.url;

    }

}

sub vcl_recv {

    #
    # Do Plone cookie sanitization, so cookies do not destroy cacheable anonymous pages.
    # Also, make sure we do not destroy WordPress admin and login cookies in the proces
    #
    if (req.http.Cookie && !(req.url ~ "wp-(login|admin)")) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(statusmessages|__ac|_ZopeId|__cp|php|PHP|wordpress_(.*))=", "; \1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

        if (req.http.Cookie == "") {
            remove req.http.Cookie;
        }
    }

    call choose_backend;

    if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&
      req.request != "OPTIONS" &&
      req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        return (pass);
    }
    return (lookup);
}

sub vcl_fetch {

    /* Use to see what cookies go through our filtering code to the server */
    /* set beresp.http.X-Varnish-Cookie-Debug = "Cleaned request cookie: " + req.http.Cookie; */

    if (beresp.ttl <= 0s ||
        beresp.http.Set-Cookie ||
        beresp.http.Vary == "*") {
        /*
         * Mark as "Hit-For-Pass" for the next 2 minutes
         */
        set beresp.ttl = 120 s;
        return (hit_for_pass);
    }
    return (deliver);
}

#
# Show custom helpful 500 page when the upstream does not respond
#
sub vcl_error {
  // Let's deliver a friendlier error page.
  // You can customize this as you wish.
  set obj.http.Content-Type = "text/html; charset=utf-8";
  synthetic {"
  <?xml version="1.0" encoding="utf-8"?>
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  <html>
    <head>
      <title>"} + obj.status + " " + obj.response + {"</title>
      <style type="text/css">
      #page {width: 400px; padding: 10px; margin: 20px auto; border: 1px solid black; background-color: #FFF;}
      p {margin-left:20px;}
      body {background-color: #DDD; margin: auto;}
      </style>
    </head>
    <body>
    <div id="page">
    <h1>Sivu ei ole saatavissa</h1>
    <p>Pahoittelemme, mutta palvelua ei ole saatavilla.</p>
    <hr />
    <h4>Debug Info:</h4>
    <pre>Status: "} + obj.status + {"
Response: "} + obj.response + {"
XID: "} + req.xid + {"</pre>
      </div>
    </body>
   </html>
  "};
  return(deliver);
}

WordPress does not support setting HTTP response headers natively like Plone. We set them in Apache virtual host configuration file in /etc/apache2/sites-enabled:

<VirtualHost 127.0.0.1:81>

    ServerName opensourcehacker.com
    ServerAlias www.opensourcehacker.com
    ServerAdmin mikko@opensourcehacker.com

    LogFormat       combined
    TransferLog     /var/log/apache2/opensourcehacker.com.log

    # Basic WordPress setup

    Options +Indexes FollowSymLinks +ExecCGI

    DocumentRoot /srv/php/opensourcehacker/wordpress

    <Directory /srv/php/opensourcehacker/wordpress>
        Options FollowSymlinks
        AllowOverride All
    </Directory>

    AddType text/css .css
    AddType application/x-httpd-php .php .php3 .php4 .php5
    AddType application/x-httpd-php-source .phps

    #
    # Set expires headers manually
    #
    ExpiresActive On
    ExpiresByType text/html A0
    ExpiresByType image/gif A3600
    ExpiresByType image/png A3600
    ExpiresByType image/image/vnd.microsoft.icon A3600
    ExpiresByType image/jpeg A3600
    ExpiresByType text/css A3600
    ExpiresByType text/javascript A3600
    ExpiresByType application/x-javascript A3600

</VirtualHost>

 Subscribe to this blog in a reader Follow me on Twitter Follow me on Facebook Follow me Google+

March 20, 2013

Lasse KarstensenVarnish paywall presentation

I held a technical presentation for Redpill Linpro about running a paywall/metered access with Varnish yesterday.

Slides as PDF are here: RL-paywall-2013-03

Main talking points were how it runs within Varnish, what extra vmods are in use, and finally how it is integrated with your backend/cms.

To keep the VS marketing department happy (Hi!), here is the link to our product page: https://www.varnish-software.com/varnish-paywall :-)

 

 


March 19, 2013

Hrafnhildur SmaradottirVarnish Software a finalist for the Red Herring Europe Top 100 Awards

The Varnish team is thrilled to announce that we are among the finalists for the 2013 Red Herring Europe Top 100 awards!

March 14, 2013

Hrafnhildur SmaradottirWhat makes the Varnish Paywall unique?

Paywalls are one of the hottest topics these days within the world of digital media. And not without reason.

February 27, 2013

Lasse KarstensenVarnish development news (Feb 2013)

An update from git:

  • Tab completion in varnishadm. (e6a88da)
  • TCP_KEEPALIVE is now enabled for all connections on operating systems that supports it. This avoids a situation where Varnish would keep retrying failing slow backend request for clients that had given up and closed the connection. (f91fc4d)
  • [3.0] The TCP_NODELAY patch introduced in September was backported into 3.0. This disables Nagle’s algorithm on connections, and avoids a situation where the last chunk of a chunked response from ESI/internal gzip got buffered by the server’s IP stack before being sent to the client. (ef5e9e0)
  • Default VCL now takes Surrogate-Control: no-store and Cache-Control: no-cache/no-store/private into account when computing TTL on a backend response. (81006ea)
  • Per took a stab at the documentation, rework underway to fit Scoof’s proposed new model.

We (Varnish Software) are looking for a junior frontend developer in Oslo, Norway. Skiing skills optional. The web page might not be updated yet, but please apply here: https://www.varnish-software.com/jobs


February 21, 2013

Hrafnhildur SmaradottirVarnish, web performance and the bottom line

The sort of web performance that Varnish can help you achieve is becoming increasingly important.

February 15, 2013

Kristian LyngstølThe Architecture the Varnish Agent

Posted on 2013-02-15

Designing software architecture is fun.

The Varnish Agent 2 was written as a replacement for the original Varnish Agent. They both share the same purpose: Expose node-specific Varnish features to a management system. They are design very differently, though.

In this post I'd like to explain some choices that were made, and show you how to write your own code for the Varnish Agent 2. It's really not that hard.

The code can be found at: https://github.com/varnish/vagent2

Why C ?

The choice of C as a language was made fairly early. One of the main reasons is that Varnish itself is written in C, as are all the tools for Varnish. This means that the by far best supported APIs for talking to Varnish are written in C.

But an other reason is because C is a very good language. It has become a false truth that you "never write web apps in C", more or less. There are good reasons for this: It takes time to set things up in C, C isn't very forgiving and perhaps most importantly: people generally suck at C.

In the end, we chose C because it was the right tool for the job.

Requirements

When designing a new system, it's important to know what you're trying to achieve, and perhaps just as important to know what you're /not/ trying to achieve.

The Varnish Agent is designed to:

  • Manage a single Varnish server.
  • Remove the need for management frontends to know the Varnish CLI language.
  • Expose log data
  • Persist configuration changes
  • Require "0" configuration of the agent itself
  • Ensure that Varnish works on boot, even if there is no management front-end present.
  • Be expandable without major re-factoring.
  • Be easy to expand

What we did NOT want was:

  • Support for running the agent on a different machine than the Varnish server.
  • Elaborate self-management of the agent (e.g: support for users, and management of them).
  • Mechanisms that are opaque to a system administrator
  • Front-end code mixed with back-end code
  • "Sessions"

We've achieved pretty much all of these goals.

The heart of the agent: The module

At the heart of the agent, there is the module. As of this writing, there are 14 modules written. The average module is 211 lines of C code (including copyright and license). The smallest module, the echo module, is 92 lines of code (the echo plugin is an example plugin with extensive self documentation). The largest modules, the vlog and vcl modules, are both 387 lines of code.

To make modules useful, I spent most of the initial work on carving out how modules should work. This is currently how it works:

  • You define a module, say, src/modules/foobar.c
  • You write foobar_init(). This function is the only absolutely required part of the function. It will be run in the single-threaded stage of the agent.
  • You either hook into other modules (like the httpd-module), or define a start function.
  • After all plugins are initialized, the start function of each plugin is executed, if present.

That's it.

Since a common task is inter-operation between plugins, an IPC mechanism was needed. I threw together a simple message passing mechanism, inspired by varnish. This lives in src/ipc.c and include/ipc.h. The only other way to currently talk to other modules is through httpd_register (and logger(), but that's just a macro for ipc_run()).

If you want your foobar.c-plugin to talk to the varnish CLI, you want to go through the vadmin-plugin. This is a two-step process:

int handle;

void foobar_init(struct agent_core_t *core)
{
    handle = ipc_register(core, "vadmin");
}

This part of the code gives you a socket to talk to the vadmin module. Actually talking to other modules in foobar_init() is not going to work, since the module isn't started yet.

And proper etiquette is not to use a global variable, but to use the plugin structure for your plugin, present in core:

struct foobar_priv_t {
        int vadmin;
}
void foobar_init(struct agent_core_t *core)
{
        struct foobar_priv_t *priv = malloc(sizeof(struct echo_priv_t));
        struct agent_plugin_t *plug;
        plug = plugin_find(core,"foobar");
        assert(plug);
        priv->vadmin = ipc_register(core,"vadmin");
        plug->data = (void *)priv;
        plug->start = NULL;
}

In this example, we have a private data structure for the module, which we allocate in the init function. Every function has a generic struct agent_plugin_t data structure already allocated for it and hooked on to the core->plugins list. This allows you to store generic data, as the core-data structure is the one typically passed around.

Note

The varnish agent uses a lot of assert()s. This is similar to what Varnish does. It lets you, the developer, state that we assume this worked, but if it didn't you really shouldn't just continue. It's excellent for catching obscure bugs before they actually become obscure. And it's excellent for letting you know where you actually need proper error code.

Let's take a closer look at the generic struct agent_plugin_t:

struct agent_plugin_t {
        const char *name;
        void *data;
        struct ipc_t *ipc;
        struct agent_plugin_t *next;
        pthread_t *(*start)(struct
                            agent_core_t *core, const
                            char *name);
        pthread_t *thread;
};

The name should be obvious. The void *data is left for the plugin to define. It can be ignored if your plugin doesn't need any data at all (what does it do?).

struct ipc_t *ipc is the IPC-structure for the plugin. This tells you that all plugins have an IPC present. This is to allow you to run ipc_register() before a plugin has initialized itself. Otherwise we'd have to worry a lot more about which order modules were loaded.

Next is *next. This is simply because the plugins are par of a linked list.

the start() function-pointer is used to define a function that will start your plugin. This function can do pretty much anything, but have to return fairly fast. If it spawns off a thread, it's expected that it will return the pthread_t * data structure, as the agent will later wait for it to join. Similar, *thread is used for the same purpose.

Using the IPC

You've got a handle to work with, let's use it. To do that, let's look at the vping plugin, starting with init and start:

static pthread_t *
vping_start(struct agent_core_t *core, const char *name)
{
        (void)name;
        pthread_t *thread = malloc(sizeof (pthread_t));
        pthread_create(thread,NULL,(*vping_run),core);
        return thread;
}

void
vping_init(struct agent_core_t *core)
{
        struct agent_plugin_t *plug;
        struct vping_priv_t *priv = malloc(sizeof(struct vping_priv_t));
        plug = plugin_find(core,"vping");

        priv->vadmin_sock = ipc_register(core,"vadmin");
        priv->logger = ipc_register(core,"logger");
        plug->data = (void *)priv;
        plug->start = vping_start;
}

vping_init() grabs a handle for the vadmin (varnish admin interface) plugin, and the logger. It also assigns vping_start() to relevant pointer.

vping_start() simply spawns a thread that runs vping_run.

static void *vping_run(void *data)
{
        struct agent_core_t *core = (struct agent_core_t *)data;
        struct agent_plugin_t *plug;
        struct vping_priv_t *ping;
        struct ipc_ret_t vret;

        plug = plugin_find(core,"vping");
        ping = (struct vping_priv_t *) plug->data;

        logger(ping->logger, "Health check starting at 30 second intervals");
        while (1) {
                sleep(30);
                ipc_run(ping->vadmin_sock, &vret, "ping");
                if (vret.status != 200)
                        logger(ping->logger, "Ping failed. %d ", vret.status);
                free(vret.answer);

                ipc_run(ping->vadmin_sock, &vret, "status");
                if (vret.status != 200 || strcmp(vret.answer,"Child in state running"))
                        logger(ping->logger, "%d %s", vret.status, vret.answer);
                free(vret.answer);
        }
        return NULL;
}

The vping module was the first module written. Written before the varnish admin interface was a module. It simply pings Varnish over the admin interface.

This also illustrates how to use the logger: Grab a handle, then use logger(handle,fmt,...), similar to how you'd use printf().

The IPC mechanism returns data through a vret-structure. For vadmin, this is precisely how Varnish would return it.

Warning

ipc_run() dynamically allocates memory for ret->answer. FREE IT.

The logger also returns a vret-like structure, but the logger() macro handles this for you.

Hooking up to HTTP!

Hooking up to HTTP is ridiculously easy.

Let's look at echo, comments removed:

struct echo_priv_t {
        int logger;
};

static unsigned int echo_reply(struct httpd_request *request, void *data)
{
        struct echo_priv_t *echo = data;
        logger(echo->logger, "Responding to request");
        send_response(request->connection, 200, request->data, request->ndata);
        return 0;
}

void echo_init(struct agent_core_t *core)
{
        struct echo_priv_t *priv = malloc(sizeof(struct echo_priv_t));
        struct agent_plugin_t *plug;
        plug = plugin_find(core,"echo");
        assert(plug);
        priv->logger = ipc_register(core,"logger");
        plug->data = (void *)priv;
        plug->start = NULL;
        httpd_register_url(core, "/echo", M_POST | M_PUT | M_GET, echo_reply, priv);
}

This is the ENTIRE echo plugin. httpd_register_url() is the key here. It register a url-base, /echo in this case, and a set of request methods (POST, PUT and GET in this case. DELETE is also supported). A callback to execute and some optional private data.

The echo_reply function is now executed every time a POST, PUT or GET request is received for URLs starting with /echo.

You can respond with send_response() as demonstrated above, or the shorthands send_response_ok(request->connection, "Things are all OK!"); and send_response_fail(request->connection, "THINGS WENT BAD");.

Warning

Currently all http requests are handled in a single thread. This means you really really shouldn't block.

But make sure it's written with thread safety in mind. We might switch to a multi-threaded request handler in the future.

Know your HTTP

"REST"-interfaces are great, if implemented correctly. A short reminder:

  • GET requests are idempotent and should not cause side effects. They should be purely informational.
  • PUT requests are idempotent, but can cause side effects. Example: PUT /start can be run multiple times.
  • POST requests do not have to be idempotent, and can cause side effects. Example: POST /vcl/ will upload new copies of the VCL.
  • DELETE requests are idempotent, and can have side effects. Example: DELETE /vcl/foobar.

Test your code!

Unused code is broken code. Untested code is also broken code.

Pretty much all functionality is tested. Take a look in tests/.

If your code is to be included in an official release, someone has to write test cases.

I also advise you to add something in html/index.html to test it if that's feasible. It also tends to be quite fun.

Getting started

To get started, grab the code and get crackin'.

I advise you to read include/*.h thoroughly.

Comments

February 13, 2013

Lasse KarstensenHTTP Live Streaming (HLS) tools

Delivering video over HTTP is up and coming. The two protocols that seem to be winning (currently) are HLS and HDS. These are my notes from playing around with HLS.

If you want to play HLS on Linux, this python player works: http://gitorious.org/hls-player . Sometimes recent VCL 2.0.3 works, but not always (and the progress bar behaves very strangely..)

If you want to dump an HLS stream to a single .ts file, use this tool: https://github.com/osklil/hls-fetch

If you want to dump a HLS VOD (video on demand, premade) stream to local disk to play with; try out my quick hls-mirror script: https://gist.github.com/anonymous/4755742

If you want to segment some media file for later video-on-demand delivery, using bleeding edge avconv (with just libx264+lamemp3) from git:

avconv -i big_buck_bunny_720p_surround.avi -vcodec h264 -acodec mp3 -hls_time 10 -hls_list_size 999999999 foo/output.m3u8

hls_list_size seems to be how many items (of the n made) that should appear in the m3u8 file. Setting to 0 actually means an empty m3u8, so useful!

The outputted files works on my android 4.1 and on my desktop.

Why all this you ask? Because video over HTTP works very well through Varnish, even better with streaming (cut-through forwarding) enabled. Even on mediocre DSL you can make a continous stream/file set, push to a Varnish on AWS/whatever, and anyone can broadcast live to the world. Slightly delayed, but standards based, simple to do and simple to scale.

I think we’ve just seen the start of how cool (and disrupting) this will become.


February 11, 2013

MacYvesDirrty Hax0r in Perl 5.12 Pid.pm for varnish-agent

Right, so I am not particularly proud of this but again, more of a note to self than anything. Secondly, I am most certainly not a Perl expert. This little hack should probably never be used or put into any production Mac setup. If you know of a proper fix, please do let me know.

Lastly, this is varnish-agent and not varnish-agent2. The former is written in Perl while the latter is written in C and uses Varnish API directly.

OK! Now that the disclaimer is out of the way, onward with the dodgy! So when running varnish-agent on OSX 10.8.2, one may encounter the following issue:

Can't kill a non-numeric process ID at /Library/Perl/5.12/File/Pid.pm line 124.

The quick fix is proposed here involves adding this line to the the Pid.pm file on line 124.

return undef unless $pid > 0;

So your subroutine in Pid.pm will end up looking more like this.

sub running {
   my $self = shift;
   my $pid  = $self->_get_pid_from_file;
   return undef unless $pid > 0;
   return   kill(0, $pid)
      ? $pid
      : undef;
}


February 08, 2013

Per BuerSecurity issues with libcurl - the curl vmod NOT affected

There is a remote code execution bug in the Curl library. One of the VMODs we support is the Curl VMOD.

February 07, 2013

Per BuerVarnish Cache as a robust distribution mechanism for HLS and HDS video

We recently came across an article on the Adobe blog that covers Adobe Media Server 5 (AMS5). AMS is an Adobe software product to help content publishers deliver video across platforms to various platforms.The article goes into details on setting up Varnish in front of AMS in order to increase performance and facilitate distribution of the content in order to build a robust video streaming solution.

February 06, 2013

Mikko OhtamaaVarnish shell singleliners: reload config, purge cache and test hits

Varnish is a server-side caching daemon. On our production server, Varnish listens to port HTTP 80 and serves at the production server front end cache; we use it mainly to serve JS, CSS and static images blazingly fast.

This blog post is based on default Varnish Ubuntu / Debian installation using apt-get. These instructions were tested on Ubuntu 12.04 LTS and Varnish 3.0.2.

1. Reload edited Varnish configs

Varnish caching rules live in /etc/varnish folder. The config entry point (main file) is /etc/varnish/default.vcl. The daemon itself (ports, etc.) is configured by /etc/defaults/varnish.

Varnish is controlled by an utility program varnishadm.You can use it in a console mode or issue direct command evaluations (think shell, MySQL client). On Ubuntu / Debian default installation varnishadm command as is is enough to control Varnish. However, on custom setup, you might need to guide it to a special console port or point it to a secret file.

Varnish config load is 2 stage process:

  • Parse and load cfg file to a Varnish memory and give it a handle you can later refer to it
  • Activate config by handle (only possible if step 1 success)

Below is an one liner shell script which generates a random handle and uses it to load the config if the config parses successfully.

HANDLE=varnish-cfg-$RANDOM ; \
  varnishadm vcl.load $HANDLE /etc/varnish/default.vcl && \
  varnishadm vcl.use $HANDLE

2. Purging Varnish cache from command line

Another useful snippet is to purge all Varnish cache from command line (invalidate all the cache):

varnishadm "ban.url ."  # Matches all URLs

Note: Command is purge.url in Varnish 2.x.

The cache is kept as shared memorymapped file in /var/lib/varnish/$INSTANCE/varnish_storage.bin. When Varnish is running it should map 1 GB (default) of your virtual memory to this file (as seen in ps, top).

You could also ban by a hostname:

varnishadm "ban req.http.host == opensourcehacker.com"

Here is a shell transcript where we observe that ban works as intended using wget utility.

# Go to /tmp because wget leaves files around
cd /tmp

# 1st load: uncached file, one X-Varnish stamp
wget -S http://opensourcehacker.com/wp-content/uploads/2011/08/Untitled-41.jpg

--2013-02-06 20:02:18--  http://opensourcehacker.com/wp-content/uploads/2011/08/Untitled-41.jpg
Resolving opensourcehacker.com (opensourcehacker.com)... 188.40.123.220
Connecting to opensourcehacker.com (opensourcehacker.com)|188.40.123.220|:80... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Server: Apache/2.2.22 (Ubuntu)
  Last-Modified: Sun, 14 Aug 2011 22:55:01 GMT
  ETag: "2000893-108ec-4aa7f09555b40"
  Cache-Control: max-age=3600
  Expires: Wed, 06 Feb 2013 23:02:19 GMT
  Content-Type: image/jpeg
  Content-Length: 67820
  Accept-Ranges: bytes
  Date: Wed, 06 Feb 2013 22:02:19 GMT
  X-Varnish: 705602514

# 2st load: cached file, two X-Varnish stamps
wget -S http://opensourcehacker.com/wp-content/uploads/2011/08/Untitled-41.jpg
--2013-02-06 20:02:21--  http://opensourcehacker.com/wp-content/uploads/2011/08/Untitled-41.jpg
Resolving opensourcehacker.com (opensourcehacker.com)... 188.40.123.220
Connecting to opensourcehacker.com (opensourcehacker.com)|188.40.123.220|:80... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Server: Apache/2.2.22 (Ubuntu)
  Last-Modified: Sun, 14 Aug 2011 22:55:01 GMT
  ETag: "2000893-108ec-4aa7f09555b40"
  Cache-Control: max-age=3600
  Expires: Wed, 06 Feb 2013 23:02:19 GMT
  Content-Type: image/jpeg
  Content-Length: 67820
  Accept-Ranges: bytes
  Date: Wed, 06 Feb 2013 22:02:22 GMT
  X-Varnish: 705602515 705602514

# Purge
varnishadm "ban.url ."

# It's non-cached again
wget -S http://opensourcehacker.com/wp-content/uploads/2011/08/Untitled-41.jpg
--2013-02-06 20:02:34--  http://opensourcehacker.com/wp-content/uploads/2011/08/Untitled-41.jpg
Resolving opensourcehacker.com (opensourcehacker.com)... 188.40.123.220
Connecting to opensourcehacker.com (opensourcehacker.com)|188.40.123.220|:80... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Server: Apache/2.2.22 (Ubuntu)
  Last-Modified: Sun, 14 Aug 2011 22:55:01 GMT
  ETag: "2000893-108ec-4aa7f09555b40"
  Cache-Control: max-age=3600
  Expires: Wed, 06 Feb 2013 23:02:35 GMT
  Content-Type: image/jpeg
  Content-Length: 67820
  Accept-Ranges: bytes
  Date: Wed, 06 Feb 2013 22:02:35 GMT
  X-Varnish: 705602516

3. Restart Varnish on Ubuntu

This forces config flush, not sure about whether cache file storage gets reset(?).

service varnish restart

4. Further ideas

If someone knowns where to get Varnish VCL syntax highlighter for Sublime Text 2 (TextMate) that would make my life easier, used in the combination SFTP plug-in.

 

 Subscribe to this blog in a reader Follow me on Twitter Follow me on Facebook Follow me Google+

MacYvesBuilding on varnish-agent2

The varnish-agent2 existing code base is pretty solid,  rather beautiful I might add. These simple words, keep it simple, has been realised by the following rule of thumb.

- Close to 0 configuration
- “Just works”
- Maintainable
- Generic
- Stateless

For those that are keen to get started on the varnish-agent2 code base, I hope that this document will be of some use. I have used a tiny subset of the Concurrent Object Modeling and architectural design mEThod (COMET), particularly the Requirements Modeling, Analysis Modeling and snippets of the actual Design Model.

Lastly, this document mostly serves as a mental note for myself :)

Requirements Modeling

The requirement for the vagent2 is to provide an extendible restful interface for varnish cache. In addition, vagent2 act as the point of integration for varnish cache with other systems – e.g. an administrative or monitoring system.

The use cases are simple right now, and is depicted in the use case diagram below.

vagent2 use cases

vagent2 use cases

Analysis Modeling

vagent2 is designed to support the full spectrum of HTTP method types. A user of the vagent2 will issue these HTTP requests and receive JSON data as response where applicable. Furthermore, the vagent2 is built with modules in mind to address a potentially expanding feature set. Lastly, each modules should be able to communicate and reused by another module.

IPC lies at the heart of the varnish-agent2 code base and message passing is the norm here for implementing an event driven model. Each module follows vagent2′s plugin paradigm, and comes equipped with the module’s own private data set. The plugin therefore follows the IPC set of callback methods, such as ipc_start and ipc_run. These methods are assigned to the appropriate functions within each module.

For the module to be exposed as a restful interface, a simple httpd_register method will hook in the module’s reply method of choice, and expose it appropriately.

For any module, the basic dependencies is depicted below.

Module breakdown

basic module dependencies

Static Modeling

varnish-agent2 ships with a few core modules, such as the logger, shmlog access, httpd and ipc modules. vstatus and vadmin provides access to the shmlog via Varnish API. Note that as of writing this blog, varnish 3.0.3 was used.

These aforementioned modules provide the building blocks for managing varnish cache. For an overview of the static models, see the class diagram below.

Static Model

Static overview of vagent2

Dynamic Modeling

Initialisation
The process of initialising a module is rather straightforward. First, add a new init method for the new module in plugins.h, ensure that you have called the init method in main.c, and of course, allocated some memory for the new plugin in main.c too.

This new module must provide an implementation of the new init method. See diagram below depicting vban’s initialisation process.

vban initialisation process

vban initialisation process

Once initialised, by hooking onto struct agent_plugin* structure, the new module will correspond to the IPC life cycle.

plugin->start  = ipc_start;
plugin->ipc->priv = your_private_plugin_data;
plugin->ipc->cb = your_plugin_callback;

plugin->start is called when your plugin starts. Note that you need to assign a start method if you want the IPC to execute your callback.

plug->ipc->priv refers to a persisted data for your plugin. This can be anything, and as a rule of thumb, this is a good place to hold references to other modules.

plug->ipc-cb refers to the callback method of when ipc_run is issued by another module.

A sample execution path

To tie it all together, the collaboration diagram below illustrate the execution path of issuing a ban to the vagent2. Note that ipc is used to reach the vadmin module.

Issue a ban

Issue a ban


January 31, 2013

Kristian LyngstølThe Varnish Agent 2.1

Posted on 2013-01-31

We just released the Varnish Agent 2.1.

(Nice when you can start a blog post with some copy/paste!)

Two-ish weeks ago we released the first version of the new Varnish Agent, and now I have the pleasure of releasing a slightly more polished variant.

The work I've put in with it the last couple of weeks has gone towards increasing stability, resilience and fault tolerance. Some changes:

  • Fixed several memory leaks
  • Fixed JSON formatting that broke the log output
  • Add privilege separation
  • Handle varnishd restart much better
  • Handle changing of the -T option without restarting the agent
  • Log assert errors to syslog
  • Add site specific javascript

For a complete-ish log, see the closed tickets for the 2.1 milestone on github.

This underlines what we seek to achieve with the agent: A rock stable operational service that just works.

If you've got any features you'd like to see in the agent, this is the time to bring them forth!

I've already started working on 2.2 which will include a much more powerful API for the varnishlog data (see docs/LOG-API.rst in the repo), and improved HTTP handling, including authentication.

So head over to the demo, play with it, if you break it, let me know! Try to install the packages and tell me about any part of the installation process that you feel is awkward or not quite right.

Comments

January 25, 2013

Per BuerSwitching behavior dynamically in Varnish

From time to time we see the need for Varnish to switch behavior based on an external event. Let's have a look at how that can be done.

January 24, 2013

Lasse KarstensenVarnish Cache development news

Short update on activities in Varnish cache development:

  • Work is being done on getting access to the request BODY inside Varnish. This feature has been requested for a while, particularly by the security.vcl guys. See daf0e2c.
  • The 2013Q1 Varnish Developer Day will be held in København February 4th.
  • I had my request approved and got req.request (which was really the HTTP method) renamed to req.method. Hurray. 0e9627d
  • Martin is steadily working on a new libvarnishapi, that makes writing varnish tools (top, stat, ncsa..) simpler. Better filtering language, more stable and better performance. Or something like that, the details are still fuzzy. :)
  • I’ve been running varnish trunk in “production” on hyse.org for a couple of weeks now. No ill effects in serving data to report. Works fine for my (minor) needs. One small note is that varnishlog fd/request grouping doesn’t work currently so you need “varnishlog -O” to get any useful output at all. The rest of the tools are probably broken as well. :)
  • On the stable side of Varnish, we (Varnish Software) have got some experience with 3.0.3 now. It seems pretty solid. Setting a backend administratively sick from varnishadm is useful.
  • The Varnish Agent 2.0 was released the other day. It is a RESTful interface in front of varnishadm, and lets you query/set stuff over HTTP. We will use it for our management tool (VAC), but it should be useful for other uses as well. Source and release announcement.

January 22, 2013

Kristian LyngstølThe Varnish Agent

Posted on 2013-01-22

We just released the Varnish Agent 2.0.

The Varnish Agent is a HTTP REST interface to control Varnish. It also provides a proof of concept front-end in html/JavaScript. In other words: A fully functional Web UI for Varnish.

We use the agent to interface between our commercial Varnish Administration Console and Varnish. This is the first agent written in C and the first version exposing a HTTP REST interface, so while 2.0 might suggest some maturity, it might be wiser to consider it a tech preview.

/misc/agent-2.0.png

I've written the agent for the last few weeks, and it's been quite fun. This is the first time I've ever written JavaScript, and it was initially just an after thought that quickly turned into something quite fun.

Some features:

  • Mostly self documenting, so it should be simple to integrate in other environments.
  • Close to 0 configuration. In fact, it currently requires 0 configuration, but might eventually require a tiny bit for authentication.
  • "Unit tests" for most functionality.
  • Upload and download VCL. Uploaded VCL is stored to disk.
  • Deploy vcl (e.g: use it). A hard link points to the most recently deployed VCL, allowing you to use that on varnish boot.
  • Show and change parameters.
  • Stop/start Varnish, show/delete panics, show status, etc
  • Varnishstat: Retrieve varnishstat data in json format
  • Varnishlog data: Retrieve varnishlog data in json format (Historic data only atm).
  • Modularised.

I've had a lot of fun hacking on this and I hope you will have some fun playing with it too!

Comments

January 19, 2013

ops42When speed doesn’t matter

Let’s talk about speed. Speed is important. Varnish is a synonym for speed. That far, that good. But am I really the only one who doesn’t get why it would be so important to be able to PURGE 4000 objects a second? Really, who the fuck cares? Wouldn’t it show a bigger problem if I [...]

January 10, 2013

Hrafnhildur SmaradottirWebinaring - a good start to the new year!

What's a good start to a new year? We feel that empowering our current and prospective customers by educating them about our offerings is the best way start to 2013.

January 09, 2013

MacYvesBuilding Varnish Cache 3.0.3 from source in Mountain Lion, OSX 10.8.2

If you want to install Varnish Cache in OSX, I highly recommend using Homebrew’s recipe for installing Varnish. Easy!

But if you want to build and run Varnish Cache from github, here is a little step-by-step checklist for you.

A shopping list of applications you’ll need for your Mountain Lion:

  • Homebrew 0.9.3
  • Xcode 4.5.2, via Appstore
  • Command Line Tool for Mountain Lion – November 1st 2012

You’ll need the following dependencies via Homebrew

  • automake, note that this has to be version 1.12. I have tested it with 1.13 and you will run into obsolete AM_CONFIG_HEADER. 
  • libtool
  • pcre
  • pkg-config

You’ll need docutils for rst2man

Run the following steps:

  1. brew install the above dependencies
  2. for automake, you will need to switch it to 1.12. See below
  3. install docutils
  4. git checkout 3.0.3 branch of Varnish Cache
  5. run ./autogen.sh
  6. run ./configure
  7. make install

To install another version of automake with Homebrew:

  1. Unlink the existing 1.13 version – brew unlink automake
  2. Get the list of versions available for automake – brew versions automake
  3. Copy the 1.12 information from git checkout…, for example git checkout 1e5eb62 /usr/local/Library/Formula/automake.rb
  4. cd into /usr/local/, or where ever else you have Homebrew storing your formula
  5. Paste the copied git information and this will check out the appropriate version of automake for you
  6. Install 1.12 – brew install automake
  7. Voila! You now have 1.12 version and you can switch between 1.13 or 1.12 by simply doing brew switch automake 1.13

January 08, 2013

Per BuerVUG6 Videos

Just before christmas we finally released the videos the BBC recorded at the last user group. Production and post processing has all been done by the BBC. We're extremely thankful to them, both for hosting the user group and recording the event.

Per BuerSub-second TTLs in Varnish Cache

Typically the backend instructs Varnish how long to cache content through the Cache-Control header. The resolution here is relatively coarse - seconds. I'll show you how to create rules for caching with sub-second precision.

December 11, 2012

Hrafnhildur SmaradottirBusiness Insider scales with Varnish - no matter what

Business Insider (BI) is an online business news site that serves 150 million pages and has around 24 million unique visitors every month. BI was launched in 2007 and has been growing fast since. Varnish has been an imperative element for scalability and web performance at BI since they first installed it in 2011. We recently talked to Pax Dickinson, Business Insider’s Chief Technology Officer, and asked him a couple of questions on how he’s been using Varnish to keep the news site stable.

December 06, 2012

Yves HwangVAC 2.0.3 with high performance cache invalidation API (aka the Super Fast Purger)

High performance cache invalidation API, introduced at the 6th Varnish user group meeting (VUG6) in London earlier this year, is now bundled with the VAC 2.0.3 release. The high performance cache invalidation API is also known as the “Super Fast Purger”.

December 05, 2012

Yves HwangVarnish Custom Statistics: our little xmas make over

Varnish Custom Statistics (VCS) now ships with a front end, helping you debug your production backend servers out of the box. With the power of VCL and the wealth of operational data contained in varnishlog, we are extremely excited about the 1.1 launch and the new possibilities the VCS now has to offer.

December 04, 2012

Ruben RomeroGetting billing data from Varnish

You can now get data from Varnish in a format that you can use to bill traffic to your customers. In the (near) future Varnish Custom Statistics will let you aggregate this data from all your Varnish servers.

November 29, 2012

Hrafnhildur SmaradottirHow the most popular women’s portal in the Middle-East became a “speedy-beast”

The most popular women's portal in the Middle-East used Varnish to greatly enhance their users web experience. They quickly saw a very positive effect on their bottom line.

November 26, 2012

Dr CarterModPageSpeed in front of Varnish

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script>

At work, we are using Varnish, a very good reverse proxy, since many years.
Varnish does a lot of stuff for us. One of the major is the ability to cache responses of our quite slow php backends. Getting a page in 16ms is ever better than 300ms :)

Since my venue to the London Velocity Conf, I am quite obsessed to test Google ModPagespeed.
The product is not focused on the frontend response time but more on the user experience.
By providing many filters, it can optimized web page applying rules like: CSS minifying, optimizing images, defer JavaScript and many others. Nothing we can’t do ourselves but it can save times of dev teams.

I have done my first test of ModPageSpeed few weeks ago. Results seems very good but one things hurts me. ModPageSpeed proceed in two stage optimization: the first call of the page, ModPageSpeed get the page from PHP and returns the response without any optimization to the client. And in parallel it launches a thread to optimize the page for the next client.
As it don’t optimize the first call, it forces a cache-control “no-cache” on the response.
The problem is that no page will go in the cache of Varnish with a no-cache directive.
One last thing, ModPageSpeed sends different optimizations depending of the User-Agent.

So, one side we have optimized the HTML of the response, increasing user experience, but on the other side we have put more load on our backend.

Thinking about it, I asked myself if we could put ModPageSpeed in front of Varnish. If yes, we could have an optimized HTML and less load on the backend.

The response is yes, we can put ModPageSpeed in front of Varnish !

We just need to install Apache and configure it with “ProxyPass”.

This is all the modules we need:

LoadModule authz_host_module /usr/lib64/httpd/modules/mod_authz_host.so
LoadModule deflate_module /usr/lib64/httpd/modules/mod_deflate.so
LoadModule log_config_module /usr/lib64/httpd/modules/mod_log_config.so
LoadModule setenvif_module /usr/lib64/httpd/modules/mod_setenvif.so
LoadModule proxy_module /usr/lib64/httpd/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib64/httpd/modules/mod_proxy_http.so
LoadModule status_module /usr/lib64/httpd/modules/mod_status.so
LoadModule vhost_alias_module /usr/lib64/httpd/modules/mod_vhost_alias.so

All others modules can be safely disabled.

Since ModPagespeed uses threads, think to start your Apache in worker mode:

HTTPD=/usr/sbin/httpd.worker

in

/etc/sysconfig/httpd

If you have more than one vhost, you need to use at least the 1.1.23.2-2191 of ModPagespeed to support multi-vhosts.

A default setup could be:

DocumentRoot "/var/www/htdocs"

<Directory />
  Order allow,deny
  Allow from all
</Directory>

Include conf.d/pagespeed.conf

NameVirtualHost *:80

<VirtualHost *:80>
  #Default VHost : ModPagespeed disabled
  ModPagespeed Off
  CustomLog /var/log/httpd/default_access.log combined
  Errorlog /var/log/httpd/default_error.log
</VirtualHost>

<VirtualHost *:80>
  #mywebsite.com VHost : ModPagespeed enabled
  ServerName www.mywebsite.com
  ServerAlias s1.mystaticwebsite.com
  ServerAlias s2.mystaticwebsite.com
  ModPagespeed On
  ModPagespeedEnableFilters lazyload_images,collapse_whitespace,combine_javascript,defer_javascript
  ModPagespeedMapOriginDomain http://localhost:8000 http://www.mywebsite.com
  ModPagespeedMapOriginDomain http://localhost:8000 http://mystaticwebsite.com
  ModPagespeedShardDomain mystaticwebsite.com s1.mystaticwebsite.com,s2.mystaticwebsite.com
  CustomLog /var/log/httpd/www.mywebsite.com_access.log combined
  Errorlog /var/log/httpd/www.mywebsite.com_error.log
</VirtualHost>

ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8000/

This configuration is fully operational but not yet tested in production.

Is there someone who has already tested this architecture in production?

November 21, 2012

Hrafnhildur SmaradottirThe stock exchange in Oslo, Oslo Børs, runs a superfast website with Varnish

After deploying Varnish the stock exchange in Oslo has reduced the response times on their website by near 80%.

November 19, 2012

Hrafnhildur SmaradottirVarnish @ Aspiro:the backbone for music streaming services

We recently talked to one of our customers here in Norway, Aspiro Music AS, the company behind WiMP, the Scandinavian music streaming service, about the innovative ways they use Varnish.

November 13, 2012

ops42Varnish is smarter than you

I just realized that a week without offending your intelligence is no good week by my standards. So here goes. Did you know that Varnish works out of the box? Provided, of course, you specify a backend to use. In a perfect world your backend would actually respond with a proper Cache-Control Header and Varnish [...]

November 06, 2012

ops42Neuter Varnish’s keep-alive connections to skip that pesky session replication

Varnish is all about speed. You know that. I know that. Heck, everybody knows that. That’s what a catchphrase is for. To that end, Varnish will keep backend connections open using keep-alive to shave off that precious milliseconds it would waste opening new ones all the time. In a world without your average application server [...]

November 05, 2012

ops42How to rid the interwebs of millions of posts about Varnish Purging

If I had to complain about something – and let’s face it, that’s what I do – I’d have to say it’s the millions of posts explaining the technique to purge something in Varnish. If it’s explained in the docs then spare me the details about how it’s supposedly done. Either stay quiet or link [...]

November 03, 2012

Hrafnhildur SmaradottirMore on international publishing media and the Varnish Paywall

We were in Frankfurt this week presenting the Varnish Paywall to representatives from international publishing media. Our fast and flexible paywall solution was received with open arms...

October 29, 2012

ops42Varnish needs to compensate for the shortcomings of oversimplified Apache configurations

I am in the fortunate situation that, for the most part, I can trust my backend responses regarding the Cache-Control headers. This spares me the tedious work of setting a proper ttl and cleaning up the response headers. Let’s face it, the cache layer cannot (and should not) always know how long a certain response [...]

ops42Varnish the gatekeeper, Rule #1

I know, it just seems too obvious to be worth mentioning, but if I have learned anything from scanning through access log files from a website with 3-digit million requests a day, it is that there is nothing that won’t be thrown your way. So better be safe than sorry and make sure only valid [...]

ops42One Varnish configuration to rule them all

As part of my day job I am “the Varnish guy” and thus have to keep track of quite some servers for the development, QA, staging and production environment. Of course there are technical differences, yet I like to have “the one” Varnish configuration for all of them. For Varnish this means different backend and [...]

October 24, 2012

Hrafnhildur SmaradottirReleasing Varnish Custom Statistics - Welcome to debugging heaven!

We are thrilled to be releasing a brand new product today: Varnish Custom Statistics (VCS). Our objective with developing it was to make the detection and diagnosis of issues on your Varnish powered website a lot easier.

October 22, 2012

Hrafnhildur SmaradottirPresenting the Varnish Paywall at the World Publishing Expo

It is becoming increasingly common that online media require their readers to pay for access to premium content by setting up paywalls. The challenge is however that paywalls can slow down websites. With our solution, The Varnish Paywall, this is no longer a problem.

October 11, 2012

Lasse KarstensenVarnish trick: Serve stale content while refetching

Here is a small trick we recently implemented for a customer:

The main premise was:

No clients should have to wait while the backend works. If a request is a miss, give the client a slightly stale/old page instead, and fetch a new page in the background.

Since Varnish and VCL is super configurable, we can do this with a VCL hack and a small helper process.

The flow is that a client requests something that just expired. In vcl_miss we notice this, and change the backend to a sick one. We also log the URL that just failed with std.log(), before restarting the request handling. Back in vcl_recv the usual sick-backend behaviour kicks in and the slightly stale graced object is given to the client.

Outside Varnish there is a small python script that tails varnishlog output for a special VCL_Log entry. When it picks it up, it sends a request for the same URL to the local Varnish. In vcl_recv we detect this client, set req.hash_always_miss to force a refetch and let the python script wait while the backend recreates the page.

All requests that come in while the refetch is underway will be served graced copies at full speed.

Your 95 percentile response time graphs will love this feature, and maybe even some of your users as well. Cool, huh?

More information about grace in Varnish:

https://www.varnish-software.com/static/book/Saving_a_request.html#core-grace-mechanisms


September 26, 2012

Ruben RomeroVarnish Training in Oct-Nov: London, Scandinavia, Online

Tollef Fog Heen, Varnish Cache Release Manager and Technical Lead at Varnish Software, will hold a 2 day training session in London, UK in October 8th & 9th.

September 25, 2012

Hrafnhildur SmaradottirWarming up for VUG6 in London

We are getting really excited about the upcoming VUG (Varnish User Group) in London next week (Friday, October 5th). The agenda is packed with interesting talks about our favourite topic.

September 19, 2012

cd34AngularJS – a first step

If you’ve not heard of AngularJS, I’m not surprised. It moves MVC or MV* to the browser and provides a unique, lightweight, powerful way to write apps that execute on the client side. Forms, validation, controllers, routes are all handled fairly easily. The one thing I look for in every framework I use is a [...]

September 14, 2012

Yves HwangVAC 2.0.2 Released!

The Varnish Administration Console 2.0.2 is released! Here are some of the enhancements we’ve done in this release:

September 04, 2012

Tollef Fog HeenDriving Jenkins using YAML and a bit of python

We recently switched from Buildbot to Jenkins at work, for building Varnish on various platforms. Buildbot worked-ish, but was a bit fiddly to get going on some platforms such as Mac OS and Solaris. Where buildbot has a daemon on each node that is responsible for contacting the central host, Jenkins uses SSH as the transport and centrally manages retries if a host goes down or is rebooted.

All in all, we are pretty happy with Jenkins, except for one thing: The job configurations are a bunch of XML files and the way you are supposed to configure this is through a web interface. That doesn't scale particularly well when you want to build many very similar jobs. We want to build multiple branches, some which are not public and we want to build on many slaves. The latter we could partially solve with matrix builds, except that will fail the entire build if a single slave fails with an error that works on retry. As the number of slaves increases, such failures become more common.

To solve this, I hacked together a crude tool that takes a yaml file and writes the XML files. It's not anywhere near as well structured and pretty as liw's jenkinstool, but it is quite good at translating the YAML into a bunch of XML files. I don't know if it's useful for anybody else, there is no documentation and so on, but if you want to take a look, it's on github.

Feedback is most welcome, as usual. Patches even more so.

September 03, 2012

Per BuerThe Varnishlog Query language

Martin is currently working on something quite exciting.

August 27, 2012

Ruben RomeroVarnish User Day (VUG6) in London, UK. Register now!

Long story, short: Register now for free to VUG6 on October 5th, 2012 @ BBC in London, UK. We have only 41 seats left (as of 2012-08-27).

ZenikaIntroducing varnishtest

When I first started working with Varnish, my only concerns were mostly configuration and a bit of administration. Depending on your needs (which can impressively become complex sometimes) you can reach the limits of Varnish in terms of features (especially if your needs are not directly linked to HTTP caching). In this case, you will probably need a module or create your own, and I've already shown you how to make one. I already knew that Varnish comes with a test framework, but I didn't expect it could also enable TDD for VMODs. I was lost when I first tried to read a test case, but I quickly found that the varnishtest framework is quite powerful and easy to use!

A test framework ?

When I stated earlier that Varnish comes with a test framework, I meant that you do have the varnishtest program when you install Varnish. It's not just a tool for the Varnish development team, nor a tool for VMOD creators. It's also a tool you can use to reproduce a bug when you file a bug report. If you look at the tests in Varnish's source tree, you can see a README:

Test-scripts for varnishtest
============================

Naming scheme
-------------

	The intent is to be able to run all scripts in lexicographic
	order and get a sensible failure mode.

	This requires more basic tests to be earlier and more complex
	tests to be later in the test sequence, we do this with the
	prefix/id letter:

		[id]%05d.vtc

	id ~ [a] --> varnishtest(1) tests
	id ~ [b] --> Basic functionality tests
	id ~ [c] --> Complex functionality tests
	id ~ [e] --> ESI tests
	id ~ [g] --> GZIP tests
	id ~ [m] --> VMOD tests
	id ~ [p] --> Persistent tests
	id ~ [r] --> Regression tests, same number as ticket
	id ~ [s] --> Slow tests, expiry, grace etc.
	id ~ [t] --> sTreaming tests
	id ~ [v] --> VCL tests: execute VRT functions

As of Varnish 3.0.3, released a few days ago, there are 294 tests you can study before writing your own. And today I'll save you some time by showing the important parts of the VTC language.

The Varnish Test Case language

Many things in Varnish's architecture are impressive for me. The design of a DSL for the configuration is one example, but I didn't expect I would find another DSL for testing when I first used with Varnish. The VTC is really easy to both write and read, but you need a small mental shift (at least I needed) because it doesn't follow the set up/test/assert/tear down or given/when/then patterns. Depending on your scenario, there might be test preparations, executions and assertions all over the place. Unlike the VCL, the VTC is not compiled but simply interpreted on the fly.

First of all, a test has a name:

varnishtest "Test example vmod"

Starting a varnishd instance

The thing about varnishtest is that it launches a real Varnish instance and interacts with it. It launches the varnishd instance, controls it through the management process and makes assertions based on the shared memory logs. It makes tests really slow (like a hundred milliseconds slow every time an expected value has yet to be found) but it actually tests the real product.

The Varnish instance needs a name. You can optionally configure it or just rely on the default VCL. If you are testing a VMOD, you can import it with an absolute file name.

varnish v1 -vcl+backend {
	import example from "${vmod_topbuild}/src/.libs/libvmod_example.so";

	sub vcl_deliver {
		set resp.http.hello = example.hello("World");
	}
} -start

The instance can be started later...

varnish v1 -vcl+backend {
	import example from "${vmod_topbuild}/src/.libs/libvmod_example.so";

	sub vcl_deliver {
		set resp.http.hello = example.hello("World");
	}
}

[...]

varnish v1 -start

If you fork the libvmod-example module, your autotools configuration will run varnishtest with the vmod_topbuild macro. It works like Java system properties in the command line: -Dkey=value.

The -vcl+backend directive automatically injects the backend into the VCL, which most of the time is what you want to do. Sometimes you might have several backends (load balanced for instance) so you might want to do it manually:

varnish v1 -vcl {
	import example from "${vmod_topbuild}/src/.libs/libvmod_example.so";

	# you'll learn how to run a "s1" server
	backend default {
		.host = "${s1_addr}";
		.port = "${s1_port}";
	}

	sub vcl_deliver {
		set resp.http.hello = example.hello("World");
	}
} -start

Now let's learn how varnishtest can mock backends and run clients.

Mocking the backend

The syntax for backends and clients is similar to the syntax for Varnish instances except that instead of VCL, you'll find actions and assertions.

server s1 {
       rxreq
       txresp
} -start

In this case, we are starting a server which answers a response to exactly one request. It could also answer to more requests, it doesn't matter. It would be a problem if the server received more requests than expected, it would timeout and the Varnish instance would send a 503 Unavailable response (yet, this is a behaviour you might need to test). Those can be seen as actions: receiving a request (rx) and transmitting (tx) a response.

Answering up to two requests:

server s1 {
       rxreq
       txresp

       rxreq
       txresp
} -start

In addition to actions, you can add assertions. You can expect the server to receive a request with a given url, a specific header... Remember that your client's request goes through a Varnish instance first and the backend request might change in some way you want to check.

server s1 {
       rxreq
       expect req.url == "/"
       txresp
} -start

It is of course possible to change the empty default response depending on your use cases.

server s1 {
       rxreq
       expect req.url == "/index.php?post/2012/07/25/RPM-Maven-Jenkins-1"
       txresp -body "A great article :p"

       rxreq
       expect req.url == "/index.php?post/2012/08/02/RPM-Maven-Jenkins-2"
       txresp -body "The second part ;)"
} -start

Once you start a server named s1, macros are automatically made available:

  • ${s1_addr} : the IP address (127.0.0.1)
  • ${s1_port} : the port (randomly chosen)
  • ${s1_sock} : the socket

It is also possible to use a real backend instead of just a mock. Remember that varnishtest launches a real varnishd instance. You could integrate Varnish in your CI environment and run your own integration or regression tests against your actual application.

Running client requests

Once you have a server and a Varnish, you can start running clients and sending requests. The syntax is the same as for the servers, but instead of expecting requests and answering responses, clients send requests and expect responses.

client c1 {
	txreq -url "/"
	rxresp
	expect resp.http.hello == "Hello, World"
} -run

And it's easy to run the same client's scenario multiple times:

client c1 {
	txreq
	rxresp
}

[...]

client c1 -run
client c1 -run
client c1 -run

And of course a single client can send several requests:

clent c1 {
	txreq -url "/index.php?post/2012/07/25/RPM-Maven-Jenkins-1"
	rxresp
	expect resp.bodylen == 18

	txreq -url "/index.php?post/2012/08/02/RPM-Maven-Jenkins-2"
	rxresp
	expect resp.bodylen == 18
} -run

We've seen that servers and clients are made to embed a scenario with both actions and expectations, embeded in the server or client body. Since a Varnish instance's body contains VCL, is it possible to add assertions ? The answer is yes.

Varnish assertions

Unlike clients or servers, Varnish assertions are put outside the instance's declaration body. What can you actually test with Varnish ? Since it's a proxy to your backend, checking requests and responses is irrelevant. Instead, you have access to the counters exposed by varnishstat at any time (it doesn't mean that all counters are relevant for testing purpose).

varnish v1 -expect the_counter == the_value 

Now, how does it look like when you write a test case that does all this ?

A more advanced example

varnishtest "Test example vmod even more"

server s1 {
       rxreq
       expect req.url == "/index.php?post/2012/07/25/RPM-Maven-Jenkins-1"
       txresp -body "A great article :p"

       rxreq
       expect req.url == "/index.php?post/2012/08/02/RPM-Maven-Jenkins-2"
       txresp -body "The second part ;)"
} -start

varnish v1 -vcl+backend {
	import example from "${vmod_topbuild}/src/.libs/libvmod_example.so";

	sub vcl_deliver {
		set resp.http.hello = example.hello("World");
	}
} -start

client c1 {
	txreq -url "/index.php?post/2012/07/25/RPM-Maven-Jenkins-1"
	rxresp
	expect resp.http.hello == "Hello, World"
	expect resp.bodylen == 18

	txreq -url "/index.php?post/2012/08/02/RPM-Maven-Jenkins-2"
	rxresp
	expect resp.http.hello == "Hello, World"
	expect resp.bodylen == 18
}

varnish v1 -expect cache_miss == 0
varnish v1 -expect cache_hit == 0

client c1 -run

varnish v1 -expect cache_miss == 2
varnish v1 -expect cache_hit == 0

client c1 -run
client c1 -run
client c1 -run

varnish v1 -expect cache_miss == 2
varnish v1 -expect cache_hit == 6

Conclusion

Test preparations, executions and assertions all over the place, didn't I warn you ? Yes I did, however, it doesn't mean that you can't write readable tests. On the contrary, the varnishtest DSL is really expressive, especially once you know how to read it. It's also easy to write, even though your test case is exploded (servers + varnish + clients), the isolation of those components makes it simpler IMHO. I should probably mention that varnishtest is not suited for performance tests by design.

This is only an introduction to varnishtest but I hope this will answer questions you might ask yourself when writing your first test cases.

August 24, 2012

Lasse KarstensenNew Varnish VMOD: Softer purges / invalidations

With the new softpurge vmod you can do cache invalidation in Varnish that only affects objects if your backend is up. This means that you can purge all you want, and in the normal case everything works as expected, but if your backend/origin server is unhappy you can serve stale content instead of a 503.

It introduces softpurge.softpurge(); where you would normally use purge; (in vcl_hit and vcl_miss).

The trick is of course that we only reduce the TTL of cached objects (and their Vary-ants), but keep the grace period. This gives us the additional win of increased concurrency while your backend recreates the content after a purge, all but the first client requesting a page withing the page creation time is served the stale one, per usual varnish grace behaviour.

You can find the vmod on my github account. Please remember that this is an early version which has not seen heavy production use yet.

PS: We’re looking into doing softer bans (the other way of doing cache invalidation in Varnish) as well. This looks to be a bit more involved, so we (Varnish Software) are looking for sponsors for this task. Ping me (or Ruben) if this sounds interesting.


August 21, 2012

Yves HwangVAC - The product, the people, part 1

A successful product sells itself. This simple statement is often preached at the top of our lungs in sales meetings. I believe this statement to be true. Though it does lack a certain tender loving care for its end users.

Per BuerVarnish Cache 3.0.3

Yesterday we released Varnish Cache 3.0.3. It's been out as a release candidate for ages, well at least a couple of months and we feel pretty certain it is solid. Gold actually.