Varnish Cache Plus

Dynamic backends (goto)

Varnish 6.0

Description

Dynamic backends in Varnish allow backends to be defined on request time instead of being predefined. For example, any request header can be used as the source for creating a backend definition.

A clear advantage of this is the possibility of DNS-backed server pool that scale up and down to accommodate the load. This is a great feature that fits well with autoscaling cloud deployments.

vmod-goto integrates with VCL to enable dynamic routing on a per-request basis.

This API applies to Varnish Cache Plus 6.0 and higher.

Goto 4.1 API

VCL example

goto behaves like vmod-directors: you first create a director object in vcl_ini that you can then use in vcl_backend_fetch. In this case, we create a pool of all the machines answering to the api.example.com domain:

import goto;

sub vcl_init {
	new apipool = goto.dns_director("api.example.com");
}

sub vcl_recv {
	set req.backend_hint = apipool.backend();
}

You can also very easily create an HTTP proxy by resolving the host header to a backend, without creating the director (ie. without knowing the hostname before hand):

    import goto;
    # goto.dns_backend() can only be used in vcl_backend_* routines
    sub vcl_backend_fetch {
            set bereq.backend = goto.dns_backend(bereq.http.host);
    }

API

Functions

goto.dns_director(STRING s, ...)

Produce a director object, a pool of machines listed by the DNS. This pool is regularly updated (every 10 seconds by default) without blocking.

You can query a backend from this director using the .backend() method. Internally, the director uses round-robin, so every time it’s used, the returned backend will change.

goto.dns_backend(STRING s, ...)

Note: It can only be called from backent-side VCL sub-routines. Calling it from anywhere else won’t return a backend.

While the dns() function solves the problem of resolving a known hostname for long-term use, sometimes an ephemeral backend is needed. This is the goal of this function.

It works the same way as dns() except that instead of a director object, it directly returns a backend to be used immediately. If multiple IPs were returned by the DNS, calling dns_backend() multiple times with the same arguments will cycle through them.

Lifetime

Such backends are cached for at least a ttl period, and can be reused if dns_backend() is called with the same arguments. This avoids making a DNS resolution per call, enabling better performance.

Once a ttl period has elapsed, two things can occur:

  • if the backend wasn’t used for this period, it is marked for death and will be destroyed as soon as it’s not used anymore. It is why .dns_backend() isn’t allowed in vcl_recv() for example: by the time it’s actually used in vcl_fetch, the backend structure may already have been destroyed.
  • if it was used, s is asynchronously resolved again and the backends stay cached for another ttl period.

Optional arguments

Both functions have the same arguments, and all but the first one are optional. Most of them are simply the same as standard backend definitions, defaults are between parenthesis:

  • STRING s: the only mandatory argument, used for the DNS resolution.
  • STRING port (none): if s didn’t specify the port, use this one. If empty too, infer it from the protocol (HTTP->80, HTTPS->443).
  • STRING host_header (none): host header to send to the backend if the bereq doesn’t have one. This is also used for TLS verification.
  • DURATION connect_timeout (none): timeout for connecting to the backends.
  • DURATION first_byte_timeout (none): timeout for the reception of the backend response.
  • DURATION between_bytes_timeout (none): timeout for receiving two consecutive bytes.
  • PROBE probe (none): probe to attach to the resolved backends.
  • INT max_connections (none): number of connections to a backend before returning 503.
  • BOOL ssl (false): enable HTTPS. If s starts with “http://” or “https://“, this is ignored
  • BOOL ssl_sni (true): if using HTTPS, enable Server Name Indication extension for backend connections.
  • BOOL ssl_verify_peer (true): enable verification of the peer’s certification chain.
  • BOOL ssl_verify_host (false): enable verification of the peer’s certificate identity.
  • ENUM ip_version [all, ipv4, ipv6] (all): restrict the IP version of resolved backend. If your DNS returns IPv6 results, make sure you have IPv6 connectivity. Note that the parameter isn’t between quotes, eg. goto.dns_director("example.com", ip_version = ipv6)
  • DURATION ttl (10s): how long should goto wait before revalidating backends.
  • ENUM ttl_rule [abide, force, morethan, lessthan] (force): conform the TTL to different rules. If abide, the TTL will be taken from the DNS resolution. If force, the TTL will be taken from the TTL parameter. If morethan, the TTL will be the resolved TTL if it is more than the TTL parameter. Otherwise it is set to the TTL parameter. If lessthan, the TTL will be the resolved TTL if it is less than the TTL parameter. Otherwise it is set to the TTL parameter. A local DNS resolution with a ttl_rule = abide, will set the backend’s ttl to 1s. This can be overwritten by using ttl_rule = force, which will set the ttl to the parameter passed into the function.

Configuration Files

vmod_goto uses /etc/nsswitch.conf to determine the order of DNS resolution and /etc/hosts for local DNS resolution. To configure the number of retries and timeout time (seconds) edit /etc/resolvconf/resolv.conf.d/tail with:

  options attempts:n
  optoins timeout:n

If neither of the above are present a default of 2 retries and a timeout time of 5 will be set. The number of retries can be between 0 and 5, while timeout time can be between 0 and 30. For the edits to go into effect, enter sudo resolvconf -u. See man resolv.conf for more information about this configuration.

Installation

vmod-goto is prebuilt for supported versions and included inside the varnish-plus package.

The package contains further usage instructions, accessible using man vmod_goto.

Contact support@varnish-software.com if you need assistance.