Libvmod-rtstatus: metriche, statistiche e vari numeri di Varnish in tempo reale.

Sono felice di introdurre un nuovo VMOD che colleziona counters e statistiche di Varnish in un JSON file e mostra questi dati tramite un’ user interface. Se vuoi sapere in tempo reale come Varnish e backends stanno lavorando, allora questo e’ il VMOD che devi usare. Questo VMOD ti permette di avere un’overview di alcuni counters di Varnish dedicando particolare attenzione a quelli relativi ai backends e alle statistiche per backend. Trovo che tutto cio’ sia assolutamente fantastico soprattutto se usi Varnish come load balancer e vuoi sapere che transazione stanno avvenendo e come Varnish sta performando.

Il VMOD si trova qui: https://github.com/varnish/libvmod-rtstatus.

Il VMOD ha due funzioni:

  • rtstatus(REAL delta): questa e la funzione responsabile della creazione del JSON file contente counters, statistiche ed altri numeri. Il parametro delta viene utilizzato per calcolare hitrate e request load, questi sono valutati su basi differenziali.

json

  • html(): il JSON file creato dalla sopracitata funzione viene passato a questa funzione che lo utilizza per creare una UI.

frontend

Riguardo quest’ultima funzione vorrei aggiungere che si tratta di un c-wrapper per un’applicazione HTML/Javascript. Questa applicazione viene presentata a Varnish come una grande stringa che poi viene utilizzata per generare un synthetic object in vcl_synth. La UI proposta nel VMOD e’ quella di default, ma puo’ essere modificata a secondo delle esigenze.
Per utilizzare il VMOD dovresti scrivere nel tuo VCL qualcosa del genere:

import rtstatus;

sub vcl_recv {
        if (req.url ~ "/rtstatus.json") {
                return(synth(700, "OK"));               }
        if (req.url ~ "/rtstatus") {
                return(synth(800, "OK"));
        }
}
sub vcl_synth {
        if (resp.status == 700){
                set resp.status = 200;
                set resp.http.Content-Type = "text/plain; charset=utf-8";
                synthetic(rtstatus.rtstatus(5));
                return (deliver);
        }
        if (resp.status == 800) {
                set resp.status = 200;
                set resp.http.Content-Type = "text/html; charset=utf-8";
                synthetic(rtstatus.html());
                return (deliver);
                }
}

Varnish come load balancer e sessioni “sticky”.

Versione originale di questo blog post (in inglese): https://www.varnish-software.com/blog/proper-sticky-session-load-balancing-varnish – scritto da Per Buer.

Assumiamo che state usando varnish come load balancer e che la vostra web application abbia necessità di mantenere determinati “dati”(ad es. un cookie_hdr)finchè la sessione è attiva. Ora, per evitare che uno user acceda a dati destinati ad un altro user, bisogna che Varnish sappia cosa sta succedendo e che una determinata sessione è relativa ad un determinato user. In pratica vogliamo che un visitatore che torna abbia tutte le volte lo stesso application server.

La soluzione è facile: basta generare una random string prima che al client(aka user che ha fatto la richiesta) venga assegnato un backend. Dopodichè bisogna rendere “persistente” la stringa generate, usando un cookie, e assicurarsi che venga ri-letta da uno user che “ritorna” sulla pagina.

Ecco il VCL d’esempio:

vcl 4.0;
import std;
import directors;
import cookie;
import header;

backend s1 {
        .host = "127.0.0.1";
        .port = "8080";
}
backend s2 {
        .host = "127.0.0.1";
        .port = "9090";

}

sub vcl_init {
    new cdir = directors.hash();
    cdir.add_backend(s1,1);
    cdir.add_backend(s2,1);
}

sub vcl_recv {
    cookie.parse(req.http.cookie);
    if (cookie.get("sticky")) {
        set req.http.sticky = cookie.get("sticky");
    } else {
        # The cookies will have floats in them. 
        # Whatever, ehh, floats your boat can be used.
        set req.http.sticky = std.random(1, 100);
    }
    # use to be client.identity in V3
    set req.backend_hint = cdir.backend(req.http.sticky);
}

sub vcl_deliver {
    # persist the cookie
    # we need to use the header vmod as there might be a set-cookie 
    # header on the object already and
    # we don't want to mess with it
    if (req.http.sticky) {
        header.append(resp.http.Set-Cookie,"sticky=bar" + req.http.sticky + "; Expires=" + cookie.format_rfc1123(now, 60m));
    }
}