Mailing List Archive

r1778 - in trunk/varnish-cache: bin/varnishd include lib/libvcl
Author: cecilihf
Date: 2007-07-27 16:16:39 +0200 (Fri, 27 Jul 2007)
New Revision: 1778

Modified:
trunk/varnish-cache/bin/varnishd/cache.h
trunk/varnish-cache/bin/varnishd/cache_center.c
trunk/varnish-cache/bin/varnishd/cache_vrt.c
trunk/varnish-cache/include/vrt.h
trunk/varnish-cache/include/vrt_obj.h
trunk/varnish-cache/lib/libvcl/vcc_action.c
trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
trunk/varnish-cache/lib/libvcl/vcc_gen_obj.tcl
trunk/varnish-cache/lib/libvcl/vcc_obj.c
trunk/varnish-cache/lib/libvcl/vcc_string.c
Log:
Added a health parameter for the backend. This is readable in vcl with backend.health.
Made it possible to pass a vcl variable to error (error 200 backend.health).
Implemented a first attempt at an algorithm for checking the health of a backend.
Negative values means the backend has problems, positive values means it is ok. 0 is neutral,
and could mean that it has been a while since the backend was asked for anything.
See the code for details.



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/bin/varnishd/cache.h 2007-07-27 14:16:39 UTC (rev 1778)
@@ -332,6 +332,11 @@

double dnsttl;
double dnstime;
+
+ int health;
+ double last_check;
+ int minute_limit;
+
#if 0
double responsetime;
double timeout;

Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c 2007-07-27 14:16:39 UTC (rev 1778)
@@ -288,10 +288,35 @@

AN(sp->bereq);
i = Fetch(sp);
+
+ /* Experimental. Set time for last check of backend health.
+ * If the backend replied with 200, it is obviously up and running,
+ * increase health parameter. If we got a 504 back, it would imply
+ * that the backend is not reachable. Decrease health parameter.
+ */
+ sp->backend->last_check = TIM_mono();
+ sp->backend->minute_limit = 1;
+ if (!i){
+ if (http_GetStatus(sp->bereq->http) == 200) {
+ if (sp->backend->health < 10000)
+ sp->backend->health++;
+ } else if(http_GetStatus(sp->bereq->http) == 504) {
+ if (sp->backend->health > -10000)
+ sp->backend->health--;
+ }
+ }
+
+
vbe_free_bereq(sp->bereq);
sp->bereq = NULL;

if (i) {
+ /* Experimental. If the fetch failed, it would also seem
+ * to be a backend problem, so decrease the health parameter.
+ */
+ if (sp->backend->health > -10000)
+ sp->backend->health--;
+
SYN_ErrorPage(sp, 503, "Error talking to backend", 30);
} else {
RFC2616_cache_policy(sp, &sp->obj->http); /* XXX -> VCL */
@@ -372,8 +397,19 @@
static int
cnt_hit(struct sess *sp)
{
+ double time_diff;
+ double minutes;

assert(!sp->obj->pass);
+
+ /* Experimental. Reduce health parameter of backend towards zero
+ * if it has been more than a minute since it was checked. */
+ time_diff = TIM_mono() - sp->backend->last_check;
+ minutes = time_diff / 60;
+ if (minutes > sp->backend->minute_limit) {
+ sp->backend->minute_limit++;
+ sp->backend->health = (int)((double)sp->backend->health / 2);
+ }

VCL_hit_method(sp);


Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2007-07-27 14:16:39 UTC (rev 1778)
@@ -289,6 +289,9 @@
cp->backend[i]->magic = BACKEND_MAGIC;
cp->backend[i]->dnsttl = 30;
TAILQ_INIT(&cp->backend[i]->connlist);
+ cp->backend[i]->health = 0;
+ cp->backend[i]->last_check = TIM_mono();
+ cp->backend[i]->minute_limit = 1;
}
}

@@ -320,6 +323,7 @@
VBACKEND(const char *, port, portname)
VBACKEND(double, dnsttl, dnsttl)

+
/*--------------------------------------------------------------------
* XXX: Working relative to t_req is maybe not the right thing, we could
* XXX: have spent a long time talking to the backend since then.
@@ -487,6 +491,15 @@
return (TIM_mono() - sp->obj->lru_stamp);
}

+int
+VRT_r_backend_health(struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
+ return sp->backend->health;
+}
+
/*--------------------------------------------------------------------*/

char *
@@ -514,6 +527,18 @@
return (q);
}

+char *
+VRT_int_string(struct sess *sp, int num)
+{
+ char *p;
+ int size = 10;
+
+ p = WS_Alloc(sp->http->ws, size);
+ AN(p);
+ snprintf(p, size, "%d", num);
+ return (p);
+}
+
/*--------------------------------------------------------------------*/

void

Modified: trunk/varnish-cache/include/vrt.h
===================================================================
--- trunk/varnish-cache/include/vrt.h 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/include/vrt.h 2007-07-27 14:16:39 UTC (rev 1778)
@@ -89,6 +89,7 @@
void VRT_fini_backend(struct backend *be);

char *VRT_IP_string(struct sess *sp, struct sockaddr *sa);
+char *VRT_int_string(struct sess *sp, int);

#define VRT_done(sp, hand) \
do { \

Modified: trunk/varnish-cache/include/vrt_obj.h
===================================================================
--- trunk/varnish-cache/include/vrt_obj.h 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/include/vrt_obj.h 2007-07-27 14:16:39 UTC (rev 1778)
@@ -46,3 +46,4 @@
const char * VRT_r_resp_response(struct sess *);
void VRT_l_resp_response(struct sess *, const char *, ...);
double VRT_r_now(struct sess *);
+int VRT_r_backend_health(struct sess *);

Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_action.c 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2007-07-27 14:16:39 UTC (rev 1778)
@@ -84,6 +84,9 @@
if (tl->t->tok == CSTR) {
Fb(tl, 0, ", %.*s", PF(tl->t));
vcc_NextToken(tl);
+ } else if (tl->t->tok == VAR) {
+ Fb(tl, 0, ", ");
+ vcc_StringVal(tl);
} else {
Fb(tl, 0, ", (const char *)0");
}

Modified: trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2007-07-27 14:16:39 UTC (rev 1778)
@@ -445,6 +445,7 @@
vsb_cat(sb, "void VRT_fini_backend(struct backend *be);\n");
vsb_cat(sb, "\n");
vsb_cat(sb, "char *VRT_IP_string(struct sess *sp, struct sockaddr *sa);\n");
+ vsb_cat(sb, "char *VRT_int_string(struct sess *sp, int);\n");
vsb_cat(sb, "\n");
vsb_cat(sb, "#define VRT_done(sp, hand) \\\n");
vsb_cat(sb, " do { \\\n");
@@ -499,4 +500,5 @@
vsb_cat(sb, "const char * VRT_r_resp_response(struct sess *);\n");
vsb_cat(sb, "void VRT_l_resp_response(struct sess *, const char *, ...);\n");
vsb_cat(sb, "double VRT_r_now(struct sess *);\n");
+ vsb_cat(sb, "int VRT_r_backend_health(struct sess *);\n");
}

Modified: trunk/varnish-cache/lib/libvcl/vcc_gen_obj.tcl
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_gen_obj.tcl 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/lib/libvcl/vcc_gen_obj.tcl 2007-07-27 14:16:39 UTC (rev 1778)
@@ -164,6 +164,10 @@
RO TIME
{recv pipe pass hash miss hit fetch deliver discard timeout}
}
+ { backend.health RO INT
+ {recv pipe pass hash miss hit fetch deliver discard timeout}
+ }
+
}

set tt(IP) "struct sockaddr *"

Modified: trunk/varnish-cache/lib/libvcl/vcc_obj.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_obj.c 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/lib/libvcl/vcc_obj.c 2007-07-27 14:16:39 UTC (rev 1778)
@@ -210,5 +210,12 @@
0,
VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_DISCARD | VCL_MET_TIMEOUT
},
+ { "backend.health", INT, 14,
+ "VRT_r_backend_health(sp)",
+ NULL,
+ V_RO,
+ 0,
+ VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_DISCARD | VCL_MET_TIMEOUT
+ },
{ NULL }
};

Modified: trunk/varnish-cache/lib/libvcl/vcc_string.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_string.c 2007-07-26 13:54:14 UTC (rev 1777)
+++ trunk/varnish-cache/lib/libvcl/vcc_string.c 2007-07-27 14:16:39 UTC (rev 1778)
@@ -140,6 +140,9 @@
case IP:
Fb(tl, 0, "VRT_IP_string(sp, %s)", vp->rname);
break;
+ case INT:
+ Fb(tl, 0, "VRT_int_string(sp, %s)", vp->rname);
+ break;
default:
vsb_printf(tl->sb,
"String representation of '%s' not implemented yet.\n",