Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Varnish: Commits

[3.0] 494c04a Add health control of backends from CLI

 

 

Varnish commits RSS feed   Index | Next | Previous | View Threaded


tfheen at varnish-cache

Apr 16, 2012, 1:20 AM

Post #1 of 1 (60 views)
Permalink
[3.0] 494c04a Add health control of backends from CLI

commit 494c04ab8cb20164317c9d44af0b032ec2bee85b
Author: Tollef Fog Heen <tfheen [at] varnish-software>
Date: Thu Nov 3 13:03:51 2011 +0100

Add health control of backends from CLI

Make it possible to mark backends as sick or healthy by way of

backend.set_health $backendname (sick|healthy|auto)

diff --git a/bin/varnishd/cache_backend.c b/bin/varnishd/cache_backend.c
index 3d6a405..b296761 100644
--- a/bin/varnishd/cache_backend.c
+++ b/bin/varnishd/cache_backend.c
@@ -259,7 +259,10 @@ vbe_Healthy(const struct vdi_simple *vs, const struct sess *sp)
backend = vs->backend;
CHECK_OBJ_NOTNULL(backend, BACKEND_MAGIC);

- if (!backend->healthy)
+ if (backend->admin_health == from_probe && !backend->healthy)
+ return (0);
+
+ if (backend->admin_health == sick)
return (0);

/* VRT/VCC sets threshold to UINT_MAX to mark that it's not
@@ -270,6 +273,9 @@ vbe_Healthy(const struct vdi_simple *vs, const struct sess *sp)
else
threshold = vs->vrt->saintmode_threshold;

+ if (backend->admin_health == healthy)
+ threshold = UINT_MAX;
+
/* Saintmode is disabled */
if (threshold == 0)
return (1);
diff --git a/bin/varnishd/cache_backend.h b/bin/varnishd/cache_backend.h
index 21a7061..25148ac 100644
--- a/bin/varnishd/cache_backend.h
+++ b/bin/varnishd/cache_backend.h
@@ -106,6 +106,12 @@ struct trouble {
* An instance of a backend from a VCL program.
*/

+enum health_status {
+ healthy,
+ sick,
+ from_probe
+};
+
struct backend {
unsigned magic;
#define BACKEND_MAGIC 0x64c4c7c6
@@ -129,6 +135,7 @@ struct backend {

struct vbp_target *probe;
unsigned healthy;
+ enum health_status admin_health;
VTAILQ_HEAD(, trouble) troublelist;

struct VSC_C_vbe *vsc;
diff --git a/bin/varnishd/cache_backend_cfg.c b/bin/varnishd/cache_backend_cfg.c
index 0582f72..215a4dc 100644
--- a/bin/varnishd/cache_backend_cfg.c
+++ b/bin/varnishd/cache_backend_cfg.c
@@ -41,6 +41,7 @@
#include <sys/socket.h>

#include "cache.h"
+#include "vcli.h"
#include "vrt.h"
#include "cache_backend.h"
#include "cli_priv.h"
@@ -232,6 +233,7 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb)
assert(b->ipv4 != NULL || b->ipv6 != NULL);

b->healthy = 1;
+ b->admin_health = from_probe;

VTAILQ_INSERT_TAIL(&backends, b, list);
VSC_C_main->n_backend++;
@@ -277,25 +279,166 @@ VRT_fini_dir(struct cli *cli, struct director *b)

/*--------------------------------------------------------------------*/

+static int
+backend_find(const char *matcher, struct backend **r, int n)
+{
+ struct backend *b;
+ char *vcl_name;
+ char *s;
+ char *match_ip = NULL;
+ char *match_port = NULL;
+ int found = 0;
+
+ s = strchr(matcher, '(');
+
+ if (s == NULL) {
+ /* Simple match, max one hit */
+ VTAILQ_FOREACH(b, &backends, list) {
+ CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+ if (strcmp(b->vcl_name, matcher) == 0) {
+ if (r && found < n)
+ r[found] = b;
+ found++;
+ }
+ }
+ return found;
+ }
+
+ vcl_name = strndup(matcher, s - matcher);
+ AN(vcl_name);
+ s++;
+ while (*s != ')') {
+ if (*s == ':') {
+ /* Port */
+ s++;
+ match_port = s;
+ if (!(s = strchr(match_port, ','))) {
+ s = strchr(match_port, ')');
+ }
+ XXXAN(s);
+ match_port = strndup(match_port, s - match_port);
+ AN(match_port);
+ if (*s == ',')
+ s++;
+ } else {
+ /* IP */
+ match_ip = s;
+ if (!(s = strchr(match_ip, ','))) {
+ s = strchr(match_ip, ')');
+ }
+ XXXAN(s);
+ match_ip = strndup(match_ip, s - match_ip);
+ AN(match_ip);
+ if (*s == ',')
+ s++;
+ }
+ }
+ VTAILQ_FOREACH(b, &backends, list) {
+ CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+ if (match_port && strcmp(b->port, match_port) != 0)
+ continue;
+ if (match_ip &&
+ (strcmp(b->ipv4_addr, match_ip) != 0) &&
+ (strcmp(b->ipv6_addr, match_ip) != 0))
+ continue;
+ if (strcmp(b->vcl_name, vcl_name) == 0) {
+ if (r && found < n)
+ r[found] = b;
+ found++;
+ }
+ }
+ return found;
+}
+
static void
-cli_debug_backend(struct cli *cli, const char * const *av, void *priv)
+cli_backend_list(struct cli *cli, const char * const *av, void *priv)
{
struct backend *b;
+ const char *ah;

(void)av;
(void)priv;
ASSERT_CLI();
+ VCLI_Out(cli, "%-30s %10s %15s %15s", "Backend name",
+ "Conns", "Probed healthy", "Admin health");
VTAILQ_FOREACH(b, &backends, list) {
+ char buf[128];
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+
+ bprintf(buf, "%s(%s,%s,%s)",
+ b->vcl_name,
+ b->ipv4_addr == NULL ? "" : b->ipv4_addr,
+ b->ipv6_addr == NULL ? "" : b->ipv6_addr, b->port);
+ if (b->admin_health == from_probe) {
+ ah = "Auto";
+ } else if (b->admin_health == sick) {
+ ah = "Sick";
+ } else {
+ ah = "Healthy";
+ }
VCLI_Out(cli, "%p %s(%s,%s,:%s) %d %d\n",
b, b->vcl_name, b->ipv4_addr, b->ipv6_addr, b->port,
b->refcount, b->n_conn);
+ VCLI_Out(cli, "\n%-30s %10d %15s %15s",
+ buf,
+ b->refcount,
+ (b ->healthy ? "Yes" : "No"),
+ ah);
+ }
+}
+
+static void
+cli_backend_set_health(struct cli *cli, const char * const *av, void *priv)
+{
+ struct backend **b;
+ enum health_status state;
+ int n;
+ const char *wstate;
+
+ (void)av;
+ (void)priv;
+ ASSERT_CLI();
+ wstate = av[3];
+ if (strcmp(wstate, "healthy") == 0) {
+ state = healthy;
+ } else if (strcmp(wstate, "sick") == 0) {
+ state = sick;
+ } else if (strcmp(wstate, "auto") == 0) {
+ state = from_probe;
+ } else {
+ VCLI_Out(cli, "Invalid state %s", wstate);
+ VCLI_SetResult(cli, CLIS_CANT);
+ return;
+ }
+ n = backend_find(av[2], NULL, 0);
+ if (n == 0) {
+ VCLI_Out(cli, "No matching backends");
+ VCLI_SetResult(cli, CLIS_CANT);
+ return;
+ }
+
+ b = calloc(n, sizeof(struct backend *));
+ AN(b);
+ n = backend_find(av[2], b, n);
+
+ VCLI_Out(cli, "Set state to %s for the following backends:", wstate);
+ for (int i = 0; i < n; i++) {
+ char buf[128];
+ bprintf(buf, "%s(%s,%s,%s)",
+ b[i]->vcl_name,
+ b[i]->ipv4_addr == NULL ? "" : b[i]->ipv4_addr,
+ b[i]->ipv6_addr == NULL ? "" : b[i]->ipv6_addr, b[i]->port);
+
+ b[i]->admin_health = state;
+ VCLI_Out(cli, "\n\t%s", buf);
}
}

-static struct cli_proto debug_cmds[] = {
- { "debug.backend", "debug.backend",
- "\tExamine Backend internals\n", 0, 0, "d", cli_debug_backend },
+static struct cli_proto backend_cmds[] = {
+ { "backend.list", "backend.list",
+ "\tList all backends\n", 0, 0, "d", cli_backend_list },
+ { "backend.set_health", "backend.set_health matcher state",
+ "\tShow a backend\n", 2, 2, "d", cli_backend_set_health },
{ NULL }
};

@@ -306,5 +449,5 @@ VBE_Init(void)
{

Lck_New(&VBE_mtx, lck_vbe);
- CLI_AddFuncs(debug_cmds);
+ CLI_AddFuncs(backend_cmds);
}
diff --git a/bin/varnishtest/tests/c00048.vtc b/bin/varnishtest/tests/c00048.vtc
new file mode 100644
index 0000000..ed8671f
--- /dev/null
+++ b/bin/varnishtest/tests/c00048.vtc
@@ -0,0 +1,55 @@
+varnishtest "Forcing health of backends"
+
+server s1 -repeat 3 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}";
+ .port = "${s1_port}";
+ .probe = {
+ .window = 8;
+ .initial = 7;
+ .threshold = 8;
+ .interval = 10s;
+ }
+ }
+
+ sub vcl_recv {
+ return(pass);
+ }
+
+} -start
+
+delay 1
+
+varnish v1 -cliok "backend.set_health s1 auto"
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 200
+} -run
+
+varnish v1 -cliok "backend.set_health s1 sick"
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 503
+} -run
+
+varnish v1 -cliok "backend.set_health s1 healthy"
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 200
+} -run
+
+varnish v1 -clierr 300 "backend.set_health s1 foo"
+varnish v1 -clierr 300 "backend.set_health s2 foo"
+varnish v1 -clierr 300 "backend.set_health s2 auto"
+

_______________________________________________
varnish-commit mailing list
varnish-commit [at] varnish-cache
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit

Varnish commits RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.