Hi Henrik:
Can you please explain in more depth what it is you are trying to
accomplish? Ignoring the code as such, focusing more on how you like
Squid to behave.
We've here a couple of Zope servers which, I really don't know in depth,
from time to time becomes lazy, accepting a TCP connection, reading
a HTTP request but simply does not answer after a read_timeout time.
I'd like to Squid assumes it is dead and after a given time make a request
again and see if the backend server answer the request. Apache with
mod_proxy_balancer behaves this way.
Attached goes another patch which is now be able to try if a 'dead' server is
answering requests after a hardcoded given time (10 seconds).
What this patch does is zeroing peer->weight which makes peerSelect()
never return it. If it becomes 'alive', original peer->weight is re-established.
I gonna look around the 'cf.data.pre' magic to probably create an option
to set the now hardcoded retrial time.
If a server accepts the TCP connection but never responds then things is
trickier as it's very hard to know how long a server will think before
it responds. There is read_timeout to abort the request, but we do not
declare the peer dead here because there could be a number of reasons
why the response took long time and very often it's isolated to a
specific URL and not the whole server.
I see.. but in our case when a given URL requested reads timeout, the
whole server is stale.
If this is not sufficient then the peer monitor function is quite
helpful in detecting malfunctioning servers, verifying nearly the
complete operations of the server at any rate you desire. Or as far as
can be verified with a request for a single URL defined in squid.conf..
Hmmm.. great. I didn't try peer monitor. I gonna take a look. Maybe it
fits our needs..
regards
Lucas Brasilino
diff -Nur squid-2.6.STABLE9.orig/src/forward.c squid-2.6.STABLE9/src/forward.c
--- squid-2.6.STABLE9.orig/src/forward.c 2007-01-18 22:21:01.000000000 -0200
+++ squid-2.6.STABLE9/src/forward.c 2007-01-31 18:50:09.000000000 -0200
@@ -1,4 +1,5 @@
+
/*
* $Id: forward.c,v 1.120 2007/01/19 00:21:01 hno Exp $
*
@@ -67,6 +68,9 @@
static Logfile *logfile = NULL;
#endif
+static void fwdServerSetDead(FwdState * fwdState);
+static void fwdServerSetAlive(FwdState * fwdState);
+
static peer *
fwdStateServerPeer(FwdState * fwdState)
{
@@ -190,14 +194,16 @@
assert(fwdState->server_fd == fd);
fwdState->server_fd = -1;
if (EBIT_TEST(fwdState->entry->flags, ENTRY_DEFER_READ))
- storeResetDefer(fwdState->entry);
+ storeResetDefer(fwdState->entry);
if (fwdCheckRetry(fwdState)) {
- int originserver = (fwdState->servers->peer == NULL);
- debug(17, 3) ("fwdServerClosed: re-forwarding (%d tries, %d secs)\n",
+ int originserver = (fwdState->servers->peer == NULL);
+ debug(17, 3) ("fwdServerClosed: re-forwarding (%d tries, %d secs)\n",
fwdState->n_tries,
- (int) (squid_curtime - fwdState->start));
+ (int) (squid_curtime - fwdState->start));
+ /* setting server dead */
+ fwdServerSetDead (fwdState);
if (fwdState->servers->next) {
- /* use next, or cycle if origin server isn't last */
+ /* use next, or cycle if origin server isn't last */
FwdServer *fs = fwdState->servers;
FwdServer **T, *T2 = NULL;
fwdState->servers = fs->next;
@@ -878,6 +884,7 @@
if (!fwdState->request->flags.pinned)
EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT);
storeRegisterAbort(e, fwdAbort, fwdState);
+ fwdServerSetAlive(fwdState);
peerSelect(r, e, fwdStartComplete, fwdState);
}
@@ -1132,3 +1139,36 @@
}
#endif
+
+static void
+fwdServerSetDead (FwdState * fwdState)
+{
+ assert (fwdState);
+ debug (17,3) ("fwdServerSetDead: setting %s (%s) dead\n",
+ fwdState->servers->peer->name,
+ fwdState->servers->peer->host);
+ fwdState->servers->peer->life.orig_weight =
+ fwdState->servers->peer->weight;
+ fwdState->servers->peer->life.death = squid_curtime;
+ fwdState->servers->peer->weight = 0;
+}
+
+static void
+fwdServerSetAlive (FwdState * fwdState)
+{
+ peer *p;
+ request_t *request = fwdState->request;
+
+ assert (fwdState);
+ for (p = Config.peers; p; p = p->next) {
+ debug (17,3) ("fwdServerSetAlive: host=%s weight=%d life.orig_weight=%d\n",p->name, p->weight, p->life.orig_weight);
+ if (neighborType (p, request) != PEER_PARENT)
+ continue;
+ if ((p->weight == 0) &&
+ (10 < (squid_curtime - p->life.death))) {
+ debug (17,3) ("fwdServerSetAlive: setting %s (%s) alive\n",
+ p->name, p->host);
+ p->weight = p->life.orig_weight;
+ }
+ }
+}
diff -Nur squid-2.6.STABLE9.orig/src/structs.h squid-2.6.STABLE9/src/structs.h
--- squid-2.6.STABLE9.orig/src/structs.h 2007-01-21 08:26:44.000000000 -0200
+++ squid-2.6.STABLE9/src/structs.h 2007-01-30 14:40:19.000000000 -0200
@@ -1439,6 +1439,10 @@
} options;
int weight;
struct {
+ int orig_weight;
+ time_t death;
+ } life;
+ struct {
double avg_n_members;
int n_times_counted;
int n_replies_expected;