November 7, 2017
22 min read time

Varnish modules (VMODs): An overview

modules.jpg
Varnish modules (VMODs): An overview
14:13

 

This is a general overview of what Varnish modules (VMODs) are available, what they do and what kind of documentation is available for each. Upcoming blog posts will cover these VMODs individually in greater detail. Be sure to subscribe to the blog so you don't miss any of these posts.

One important thing to keep in mind about VMODs: they are powerful and convenient and help you do a lot of things. But you have to retrieve, build and install/update VMODs yourself if you're not using Varnish Plus. Varnish Plus customers receive packages, which contributes a lot of ease of use and saving time - a lot easier to handle and manage. Naturally this can be as important as the features the VMODs enable.

The Varnish Configuration Language (VCL) is the domain specific language of Varnish. This language is very powerful and efficient for most tasks a cache server performs. However, sometimes you might need more functionalities, e.g., looking up an IP address in a database, or modularizing your code. Varnish modules (VMODs) exist for precisely these kinds of reasons.

VMODs are C code compiled as shared libraries, which can be called from VCL code. Compared to inline C, VMODs are much easier to maintain and are more secure. Every VMOD must come with a .vcc documentation file that can be compiled into a manual page or online documentation. This, together with the fact that VMODs are modules, makes it easier to share code and easier to debug in collaboration with other developers.

Table 1 presents an overview of the available VMODs we package and support in Varnish Plus. The second column, Varnish Plus only, marks those VMODs that are available only for Varnish Plus customers. The third column, Varnish Cache VMODs in Varnish Plus packages, marks those modules that are also available in Varnish Cache, and we bundle them in Varnish Plus (Varnish Plus customers have support also for these VMODs).

Table 1: Availability of Varnish modules (VMODs)
VMOD Varnish Plus Varnish Cache
bodyaccess
cookie
debug
directors
header
saintmode
softpurge
std
tcp
var
vsthrottle
xkey
acl  
cookie-plus  
edgestash  
goto  
http  
json  
kvstore  
leastconn  
paywall  
rewrite  
rtstatus  
session  

Besides the VMODs presented here, there are many open source VMODs. An ongoing effort to describe them can be found at https://varnish-cache.org/vmods/. Next is a short description the VMODs listed in Table 1.

1. acl

This module allows you to match IP addresses against ACLs similar to the built-in VCL ACL implementation. The key difference is that your ACLs do not need to be bound to the active VCL and can be stored as strings in a separate VMOD or even backend responses.

Currently, only IPv4 addresses and subnets are supported. Entries can be prepended with the exclamation mark ! for a negative match.

Further reading

2. bodyaccess

This VMOD is primarily used when including the request body in the hashing function. We have made a tutorial that demonstrates this: https://docs.varnish-software.com/tutorials/caching-post-requests/.

Further reading

3. cookie

This module handles HTTP cookies more easily (without regex) in VCL. It parses a cookie header into an internal data store, where per-cookie get/set/delete functions are available. A filter_except() method removes all but a set comma-separated list of cookies. A filter() method removes a comma-separated list of cookies.

A convenience function for formatting the Expires directive (in the Set-Cookie HTTP response header) is also included. If there are multiple Set-Cookie headers, vmod-header should be used.

4. debug

This module contains a set of utility functions for the developers of Varnish and VMODs. You should not use this module unless you have a deep understanding of Varnish internals. This VMOD is typically used only by Varnish core developers.

5. directors

This module enables backend load balancing in Varnish and implements a set of basic load balancing techniques.

For VMOD writers, it serves as an example of how one could extend the load balancing capabilities of Varnish.

6. edgestash

This module is a real-time templating engine for JSON objects. Varnish can assign a JSON object to each response, which enables truly dynamic responses. JSON objects can either be fetched from a backend or generated in VCL.

An Edgestash template is fetched and compiled into response optimized byte code and then stored into cache. This byte code is then executed on delivery, efficiently streaming the response to the client using a zero-parse and zero-copy algorithm. JSON is also stored into cache as a fast search index.

Edgestash currently supports the full Mustache spec, and is available in Varnish Cache Plus 4.1.6r2 and later.

Further reading

7. goto

This module enables dynamic backends in Varnish, which enables dynamic routing on a per-request basis. Dynamic backends are those backends defined by request time rather than being predefined.

The goto VMOD can use any HTTP request header as the source to define backends. A clear advantage of this is the possibility of deploying a DNS-backed server pool that scales up and down to accommodate requests load. This feature fits well with autoscaling cloud deployments.

8. header

This module manipulates duplicated HTTP headers, for instance multiple Set-Cookie headers.

Further reading

9. http

This module allows Varnish to control HTTP communication. It can be found in the vmods-extras package. The module supports both synchronous and asynchronous communication, and it has automatic loop detection and prefetch URL generation capabilities. The prefetch capability is particularly useful for video on demand (VoD) and live video streaming servers.

Further reading

10. kvstore

This module allows you to manage a high-performance key-value store from VCL. The database is in-memory only, and supports setting a TTL (Time To Live) when a key-value pair is inserted.

kvstore is good example of a VMOD that fundamentally extends the capabilities of VCL. With kvstore you can, for example, create a hash table to solve problems in high-level languages data organization.

11. leastconn

This VMOD implements the least connections director for Varnish. With this director, Varnish will send client requests to the backend with the least number of active connections.

Each backend has an associated weight. A backend with, e.g. weight 10 will receive twice the number of client requests as a backend with weight 5.

12. paywall

This module contains functions to ease the configuration of the Varnish Paywall.

Further reading

13. rewrite

This module aims at reducing the amount of VCL code dedicated to URL and HTTP headers manipulation. The usual way of handling things in VCL is a long list of if-else clauses:

sub vcl_recv {
        if (req.url ~ "pattern1") {
                set req.url = regsub(req.url, "regex1", "substitute1");
                else if (req.url ~ "pattern2") {
                        set req.url = regsub(req.url, "regex2", "substitute2");
                        ...
                }
        }
}

Using vmod_rewrite, the VCL boils down to:

sub vcl_init {
        new rs = rewrite.ruleset("/path/to/file.rules");
}

sub vcl_recv {
        set req.url = rs.replace(req.url);
}

where file.rules contains:

"regex1" "subtitute1"
"regex2" "subtitute2"
...

14. rtstatus

This module lets you query your Varnish server for a JSON object containing counters. For example, visiting the URL /rtstatus.json on Varnish will produce an application/json response in the following format:

{
  "uptime" : "0+16:12:58",
  "uptime_sec": 58378.00,
  "hitrate": 30.93,
  "load": 2.73,
  "varnish_version" : "varnish-plus-4.1.2r1 revision 4d86388",
  "server_id": "ubuntu-14",
  "be_info":
  [
    {"server_name":"boot.default", "happy": 0, "bereq_tot": 13585163,"beresp_tot": 290463715,"pipe_hdrbytes": 0,"pipe_out": 0,"pipe_in": 0,"conn": 82094,"req": 82094},
    {"server_name":"boot.server1", "happy": 0, "bereq_tot": 0,"beresp_tot": 0,"pipe_hdrbytes": 0,"pipe_out": 0,"pipe_in": 0,"conn": 0,"req": 0},
  ]
    "VBE.boot.default.happy": {"type": "VBE", "ident": "boot.default", "descr": "Happy health probes", "value": 0},
  "VBE.boot.default.bereq_hdrbytes": {"type": "VBE", "ident": "boot.default", "descr": "Request header bytes", "value": 13585163},
  "VBE.boot.default.bereq_bodybytes": {"type": "VBE", "ident": "boot.default", "descr": "Request body bytes", "value": 0},
}

Whereas visiting the URL /rtstatus on Varnish will produce an application/javascript response.

15. saintmode

This module lets you deal with a backend that is failing in random ways for specific requests. It maintains a blacklist per backend, marking the backend as sick for specific objects. When the number of objects marked as sick for a backend reaches a set threshold, the backend is considered sick for all requests. Each blacklisted object carries a TTL, which denotes the time it will stay blacklisted.

16. session

This module lets you manipulate local variables of sessions. This can be used to improve setups where Varnish acts both as a backend for Akamai and as a normal server for regular clients. At the time of writing this blog, only the idle timeout can be accessed. Example:

sub vcl_recv {
        if(...) {
                session.set_timeout_idle(300s);
        }
}

Further reading

17. softpurge

This module is used to implement a cache invalidation strategy that allows Varnish to reply to client requests using the cached object and updating it in parallel. softpurge reduces TTL but keeps the grace value of a resource.

18. std

This is the standard VMOD, where the Varnish developers have added various utility functions. Most VCLs use at least one function from this VMOD. Function definitions are the following:

VOID cache_req_body(BYTES)
VOID collect(HEADER)
DURATION duration(STRING, DURATION)
BOOL file_exists(STRING)
STRING fileread(PRIV_CALL, STRING)
STRING getenv(STRING)
BOOL healthy(BACKEND)
INT integer(STRING, INT)
IP ip(STRING, IP)
VOID log(STRING_LIST)
INT port(IP)
STRING querysort(STRING)
REAL random(REAL, REAL)
REAL real(STRING, REAL)
INT real2integer(REAL, INT)
TIME real2time(REAL, TIME)
VOID rollback(HTTP)
VOID set_ip_tos(INT)
STRING strstr(STRING, STRING)
VOID syslog(INT, STRING_LIST)
TIME time(STRING, TIME)
INT time2integer(TIME, INT)
REAL time2real(TIME, REAL)
VOID timestamp(STRING)
STRING tolower(STRING_LIST)
STRING toupper(STRING_LIST)

19. tcp

This module allows for changing attributes of TCP connections in your VCL code. The primary use is for rate limiting (pacing) using the fair queuing (FQ) network scheduler on recent Linux systems.

Further reading

20. var

This module implements basic variable support in VCL. It supports strings, integers and real numbers. There are methods to get and set each variable.

There are global and local variables. Global variables have a lifespan that extends across requests and VCL programs, for as long as the VMOD is loaded. Local variables are cleaned up at the end of a request.

21. vsthrottle

This module limits the traffic rate on a Varnish server. It offers a simple interface for throttling traffic on a per-key basis to a specific request rate. Keys can be specified from any string, e.g., based on client.ip, a specific cookie value, or an API token.

The request rate is specified as the number of requests permitted over a period. This VMOD implements a Token bucket.

Further reading

22. xkey

This module adds a secondary hash key, called xkey, to cached objects. This enables purging across all objects with the same xkey. You can use xkey to indicate relationships, and think about it as tag. It is possible to assign more than one key to an object.

Two good use cases are:

  1. news sites that add a xkey to all articles that about same event, or
  2. e-commerce sites that add a xkey to each stock keeping unit (SKU) of the products presented in a page.

23. cookie-plus

This module is an advanced cookie VMOD for interacting with request and response cookies. vmod-cookieplus allows you to:

  • get, add, delete, and keep Cookie and Set-Cookie values
  • remove unused client side Cookies

24. json

This module parses JSON strings. It can also create JSON contexts out from parsing request and response bodies.

Further reading

Visit Varnish documentation to learn more and stay tuned and subscribe to the blog for more detailed posts about the VMODs and what they can do for you.

GO IN-DEPTH WITH VARNISH DOCUMENTATION

Photo by Raphael Koh on Unsplash