---------- Forwarded message ----------
Date: Mon, 04 Oct 2004 17:06:44 +0200
From: Stephane DAVY <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: [squid-users] Patch for load-balancing et HA in Squid-ICAP client
Hello,
please find below a message posted on the squid-icapClient ML. Actually,
there is not so much activity on this list even if people are interested
in ICAP stuff in Squid. This message deals with HA and load-balancing,
and testing is needed so any feedback is welcome.
Thanks,
Stéphane
Objet: [squid-icapClient] Patch for load-balancing et HA
Date: Mon, 04 Oct 2004 14:54:34 +0200
Hello all,
here is a patch from Luc Saillard (Alcove company) which implements
load-balancing and HA. You can define a service using different
serveurs, and for each request we take the next server if this one is
reachable:
icap_service service_1 reqmod_precache icap://server1:1344/wwreqmod
icap_service service_1 reqmod_precache icap://server2:1344/wwreqmod
icap_service service_1 reqmod_precache icap://server3:1344/wwreqmod
The patch should be applied against the latest tarball available here:
http://www.squid-cache.org/~wessels/squid-icap-2.5/
Dont' forget to run bootstrap.sh before configure
Feedback is welcome at the following address:
[EMAIL PROTECTED] and of course on this ML
Enjoy!
--
Stephane DAVY <[EMAIL PROTECTED]>
--- squid-icap-2.5-200409161544.orig/src/cache_cf.c Wed Aug 4 21:47:58 2004
+++ squid-icap-2.5-200409161544/src/cache_cf.c Tue Sep 28 15:44:03 2004
@@ -2299,13 +2299,27 @@
*/
static void
-icap_service_list_add(icap_service_list ** isl, icap_service * service)
+icap_service_list_add(icap_service_list ** isl, char * service_name)
{
icap_service_list **iter;
icap_service_list *new;
+ icap_service *gbl_service;
+ int i;
+ int max_services;
new = memAllocate(MEM_ICAP_SERVICE_LIST);
- new->service = service;
+ /* Found all services with that name, and add to the array */
+ max_services = sizeof(new->services)/sizeof(icap_service *);
+ gbl_service = Config.icapcfg.service_head;
+ i=0;
+ while(gbl_service && i < max_services) {
+ if (!strcmp(service_name, gbl_service->name)) {
+ new->services[i++] = gbl_service;
+ break;
+ }
+ gbl_service = gbl_service->next;
+ }
+ new->nservices = i;
if (*isl) {
iter = isl;
@@ -2400,7 +2414,7 @@
for (iter = c->services; iter; iter = iter->next) {
service = icap_service_lookup(iter->key);
if (service) {
- icap_service_list_add(&isl, service);
+ icap_service_list_add(&isl, iter->key);
} else {
debug(3, 0) ("icap_class_process (line %d): skipping service %s in class %s\n", config_lineno, iter->key, c->name);
}
@@ -2493,7 +2507,9 @@
c->hidden = 1;
wordlistAdd(&c->services, A->service_name);
c->isl = memAllocate(MEM_ICAP_SERVICE_LIST);
- c->isl->service = s;
+ /* FIXME:luc: check what access do */
+ c->isl->services[0] = s;
+ c->isl->nservices = 1;
icap_class_add(c);
A->class = c;
} else {
@@ -2592,7 +2608,9 @@
printf(" %s: \n", c_iter->name);
printf(" services = \n");
for (isl_iter = c_iter->isl; isl_iter; isl_iter = isl_iter->next) {
- printf(" %s\n", isl_iter->service->name);
+ int i;
+ for (i = 0; i < isl_iter->nservices; i++)
+ printf(" %s\n", isl_iter->services[i]->name);
}
}
debug(3, 0) ("IcapConfig: access =\n");
--- squid-icap-2.5-200409161544.orig/src/icap_common.c Sat Apr 3 23:12:55 2004
+++ squid-icap-2.5-200409161544/src/icap_common.c Tue Sep 28 15:36:03 2004
@@ -140,6 +140,8 @@
icapService(icap_service_t type, request_t * r)
{
icap_service_list *isl_iter;
+ int is_iter;
+
debug(81, 8) ("icapService: type=%s\n", icapServiceToStr(type));
if (NULL == r) {
debug(81, 8) ("icapService: no request_t\n");
@@ -150,10 +152,27 @@
return NULL;
}
for (isl_iter = r->class->isl; isl_iter; isl_iter = isl_iter->next) {
- if (type == isl_iter->service->type) {
- debug(81, 8) ("icapService: found service %s\n", isl_iter->service->name);
- return isl_iter->service;
- }
+ /* TODO:luc: Do a round-robin, choose a random value ?
+ * For now, we use a simple round robin with checking is the
+ * icap server is available */
+ is_iter = isl_iter->last_service_used;
+ do
+ {
+ is_iter = (is_iter + 1) % isl_iter->nservices;
+ debug(81, 9) ("icapService: checking service %s/id=%d\n",isl_iter->services[is_iter]->name,is_iter);
+ if (type == isl_iter->services[is_iter]->type)
+ {
+ if (!isl_iter->services[is_iter]->unreachable)
+ {
+ debug(81, 8) ("icapService: found service %s/id=%d\n", isl_iter->services[is_iter]->name,is_iter);
+ isl_iter->last_service_used = is_iter;
+ return isl_iter->services[is_iter];
+ }
+ debug(81, 8) ("icapService: found service %s/id=%d, but it's unreachable. I don't want to use it\n", isl_iter->services[is_iter]->name,is_iter);
+ /* FIXME:luc: in response mod, if we return an NULL pointer, user can bypass
+ * the filter, is it normal ? */
+ }
+ } while (is_iter != isl_iter->last_service_used);
}
debug(81, 8) ("icapService: no service found\n");
return NULL;
--- squid-icap-2.5-200409161544.orig/src/structs.h Wed Aug 4 21:48:08 2004
+++ squid-icap-2.5-200409161544/src/structs.h Tue Sep 28 13:05:08 2004
@@ -1085,7 +1085,9 @@
struct _icap_service_list {
icap_service_list *next;
- icap_service *service;
+ icap_service *services[16];
+ int nservices; /* Number of services already used */
+ int last_service_used; /* Last services used, use to do a round robin */
};
struct _icap_class {