mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
Add in a very simple balancer "set" concept, which allows
for members to be assigned to a particular cluster set such that members in lower-numbered sets are checked/used before those in higher ones. Also bundled in this are some HTML cleanups for the balancer manager UI. Sorry for the mixins :) Compiles/builds clean: passes test framework as well as more normal usage tests ;) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@427172 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -2,6 +2,10 @@
|
|||||||
Changes with Apache 2.3.0
|
Changes with Apache 2.3.0
|
||||||
[Remove entries to the current 2.0 and 2.2 section below, when backported]
|
[Remove entries to the current 2.0 and 2.2 section below, when backported]
|
||||||
|
|
||||||
|
*) mod_proxy_balancer: Workers can now be defined as part of
|
||||||
|
a balancer cluster "set" in which members of a lower-numbered set
|
||||||
|
are preferred over higher numbered ones. [Jim Jagielski]
|
||||||
|
|
||||||
*) SECURITY: CVE-2006-3747 (cve.mitre.org)
|
*) SECURITY: CVE-2006-3747 (cve.mitre.org)
|
||||||
mod_rewrite: Fix an off-by-one security problem in the ldap scheme
|
mod_rewrite: Fix an off-by-one security problem in the ldap scheme
|
||||||
handling. For some RewriteRules this could lead to a pointer being
|
handling. For some RewriteRules this could lead to a pointer being
|
||||||
|
@@ -253,6 +253,12 @@ static const char *set_worker_param(apr_pool_t *p,
|
|||||||
worker->ping_timeout = apr_time_from_sec(ival);
|
worker->ping_timeout = apr_time_from_sec(ival);
|
||||||
worker->ping_timeout_set = 1;
|
worker->ping_timeout_set = 1;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(key, "lbset")) {
|
||||||
|
ival = atoi(val);
|
||||||
|
if (ival < 0 || ival > 99)
|
||||||
|
return "lbset must be between 0 and 99";
|
||||||
|
worker->lbset = ival;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return "unknown Worker parameter";
|
return "unknown Worker parameter";
|
||||||
}
|
}
|
||||||
@@ -1898,7 +1904,7 @@ static int proxy_status_hook(request_rec *r, int flags)
|
|||||||
ap_rputs("\n\n<table border=\"0\"><tr>"
|
ap_rputs("\n\n<table border=\"0\"><tr>"
|
||||||
"<th>Sch</th><th>Host</th><th>Stat</th>"
|
"<th>Sch</th><th>Host</th><th>Stat</th>"
|
||||||
"<th>Route</th><th>Redir</th>"
|
"<th>Route</th><th>Redir</th>"
|
||||||
"<th>F</th><th>Acc</th><th>Wr</th><th>Rd</th>"
|
"<th>F</th><th>Set</th><th>Acc</th><th>Wr</th><th>Rd</th>"
|
||||||
"</tr>\n", r);
|
"</tr>\n", r);
|
||||||
|
|
||||||
worker = (proxy_worker *)balancer->workers->elts;
|
worker = (proxy_worker *)balancer->workers->elts;
|
||||||
@@ -1917,6 +1923,7 @@ static int proxy_status_hook(request_rec *r, int flags)
|
|||||||
ap_rvputs(r, "</td><td>", worker->s->route, NULL);
|
ap_rvputs(r, "</td><td>", worker->s->route, NULL);
|
||||||
ap_rvputs(r, "</td><td>", worker->s->redirect, NULL);
|
ap_rvputs(r, "</td><td>", worker->s->redirect, NULL);
|
||||||
ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor);
|
ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor);
|
||||||
|
ap_rprintf(r, "<td>%d</td>", worker->s->lbset);
|
||||||
ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>", worker->s->elected);
|
ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>", worker->s->elected);
|
||||||
ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
|
ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
|
||||||
ap_rputs("</td><td>", r);
|
ap_rputs("</td><td>", r);
|
||||||
|
@@ -289,6 +289,8 @@ typedef struct {
|
|||||||
char route[PROXY_WORKER_MAX_ROUTE_SIZ+1];
|
char route[PROXY_WORKER_MAX_ROUTE_SIZ+1];
|
||||||
char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1];
|
char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1];
|
||||||
void *context; /* general purpose storage */
|
void *context; /* general purpose storage */
|
||||||
|
apr_size_t busy; /* busyness factor */
|
||||||
|
int lbset; /* load balancer cluster set */
|
||||||
} proxy_worker_stat;
|
} proxy_worker_stat;
|
||||||
|
|
||||||
/* Worker configuration */
|
/* Worker configuration */
|
||||||
@@ -309,31 +311,32 @@ struct proxy_worker {
|
|||||||
apr_interval_time_t ttl; /* maximum amount of time in seconds a connection
|
apr_interval_time_t ttl; /* maximum amount of time in seconds a connection
|
||||||
* may be available while exceeding the soft limit */
|
* may be available while exceeding the soft limit */
|
||||||
apr_interval_time_t timeout; /* connection timeout */
|
apr_interval_time_t timeout; /* connection timeout */
|
||||||
char timeout_set;
|
char timeout_set;
|
||||||
apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
|
apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
|
||||||
char acquire_set;
|
char acquire_set;
|
||||||
apr_size_t recv_buffer_size;
|
apr_size_t recv_buffer_size;
|
||||||
char recv_buffer_size_set;
|
char recv_buffer_size_set;
|
||||||
apr_size_t io_buffer_size;
|
apr_size_t io_buffer_size;
|
||||||
char io_buffer_size_set;
|
char io_buffer_size_set;
|
||||||
char keepalive;
|
char keepalive;
|
||||||
char keepalive_set;
|
char keepalive_set;
|
||||||
proxy_conn_pool *cp; /* Connection pool to use */
|
proxy_conn_pool *cp; /* Connection pool to use */
|
||||||
proxy_worker_stat *s; /* Shared data */
|
proxy_worker_stat *s; /* Shared data */
|
||||||
void *opaque; /* per scheme worker data */
|
void *opaque; /* per scheme worker data */
|
||||||
int is_address_reusable;
|
int is_address_reusable;
|
||||||
#if APR_HAS_THREADS
|
#if APR_HAS_THREADS
|
||||||
apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */
|
apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */
|
||||||
#endif
|
#endif
|
||||||
void *context; /* general purpose storage */
|
void *context; /* general purpose storage */
|
||||||
enum {
|
enum {
|
||||||
flush_off,
|
flush_off,
|
||||||
flush_on,
|
flush_on,
|
||||||
flush_auto
|
flush_auto
|
||||||
} flush_packets; /* control AJP flushing */
|
} flush_packets; /* control AJP flushing */
|
||||||
int flush_wait; /* poll wait time in microseconds if flush_auto */
|
int flush_wait; /* poll wait time in microseconds if flush_auto */
|
||||||
apr_interval_time_t ping_timeout;
|
apr_interval_time_t ping_timeout;
|
||||||
char ping_timeout_set;
|
char ping_timeout_set;
|
||||||
|
int lbset; /* load balancer cluster set */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -100,6 +100,7 @@ static int init_balancer_members(proxy_server_conf *conf, server_rec *s,
|
|||||||
/* Set to the original configuration */
|
/* Set to the original configuration */
|
||||||
workers[i].s->lbstatus = workers[i].s->lbfactor =
|
workers[i].s->lbstatus = workers[i].s->lbfactor =
|
||||||
(workers[i].lbfactor ? workers[i].lbfactor : 1);
|
(workers[i].lbfactor ? workers[i].lbfactor : 1);
|
||||||
|
workers[i].s->lbset = workers[i].lbset;
|
||||||
}
|
}
|
||||||
/* Set default number of attempts to the number of
|
/* Set default number of attempts to the number of
|
||||||
* workers.
|
* workers.
|
||||||
@@ -622,6 +623,12 @@ static int balancer_handler(request_rec *r)
|
|||||||
else if (!strcasecmp(val, "Enable"))
|
else if (!strcasecmp(val, "Enable"))
|
||||||
wsel->s->status &= ~PROXY_WORKER_DISABLED;
|
wsel->s->status &= ~PROXY_WORKER_DISABLED;
|
||||||
}
|
}
|
||||||
|
if ((val = apr_table_get(params, "ls"))) {
|
||||||
|
int ival = atoi(val);
|
||||||
|
if (ival >= 0 && ival <= 99) {
|
||||||
|
wsel->s->lbset = ival;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (apr_table_get(params, "xml")) {
|
if (apr_table_get(params, "xml")) {
|
||||||
@@ -684,13 +691,13 @@ static int balancer_handler(request_rec *r)
|
|||||||
ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
|
ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
|
||||||
"<th>Worker URL</th>"
|
"<th>Worker URL</th>"
|
||||||
"<th>Route</th><th>RouteRedir</th>"
|
"<th>Route</th><th>RouteRedir</th>"
|
||||||
"<th>Factor</th><th>Status</th>"
|
"<th>Factor</th><th>Set</th><th>Status</th>"
|
||||||
"<th>Elected</th><th>To</th><th>From</th>"
|
"<th>Elected</th><th>To</th><th>From</th>"
|
||||||
"</tr>\n", r);
|
"</tr>\n", r);
|
||||||
|
|
||||||
worker = (proxy_worker *)balancer->workers->elts;
|
worker = (proxy_worker *)balancer->workers->elts;
|
||||||
for (n = 0; n < balancer->workers->nelts; n++) {
|
for (n = 0; n < balancer->workers->nelts; n++) {
|
||||||
|
char fbuf[50];
|
||||||
ap_rvputs(r, "<tr>\n<td><a href=\"", r->uri, "?b=",
|
ap_rvputs(r, "<tr>\n<td><a href=\"", r->uri, "?b=",
|
||||||
balancer->name + sizeof("balancer://") - 1, "&w=",
|
balancer->name + sizeof("balancer://") - 1, "&w=",
|
||||||
ap_escape_uri(r->pool, worker->name),
|
ap_escape_uri(r->pool, worker->name),
|
||||||
@@ -698,7 +705,8 @@ static int balancer_handler(request_rec *r)
|
|||||||
ap_rvputs(r, worker->name, "</a></td>", NULL);
|
ap_rvputs(r, worker->name, "</a></td>", NULL);
|
||||||
ap_rvputs(r, "<td>", worker->s->route, NULL);
|
ap_rvputs(r, "<td>", worker->s->route, NULL);
|
||||||
ap_rvputs(r, "</td><td>", worker->s->redirect, NULL);
|
ap_rvputs(r, "</td><td>", worker->s->redirect, NULL);
|
||||||
ap_rprintf(r, "</td><td>%d</td><td>", worker->s->lbfactor);
|
ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor);
|
||||||
|
ap_rprintf(r, "<td>%d</td><td>", worker->s->lbset);
|
||||||
if (worker->s->status & PROXY_WORKER_DISABLED)
|
if (worker->s->status & PROXY_WORKER_DISABLED)
|
||||||
ap_rputs("Dis ", r);
|
ap_rputs("Dis ", r);
|
||||||
if (worker->s->status & PROXY_WORKER_IN_ERROR)
|
if (worker->s->status & PROXY_WORKER_IN_ERROR)
|
||||||
@@ -712,10 +720,11 @@ static int balancer_handler(request_rec *r)
|
|||||||
if (!PROXY_WORKER_IS_INITIALIZED(worker))
|
if (!PROXY_WORKER_IS_INITIALIZED(worker))
|
||||||
ap_rputs("-", r);
|
ap_rputs("-", r);
|
||||||
ap_rputs("</td>", r);
|
ap_rputs("</td>", r);
|
||||||
ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td>", worker->s->elected);
|
ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>", worker->s->elected);
|
||||||
ap_rprintf(r, "<td>%" APR_OFF_T_FMT "</td>", worker->s->transferred);
|
ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
|
||||||
ap_rprintf(r, "<td>%" APR_OFF_T_FMT "</td>", worker->s->read);
|
ap_rputs("</td><td>", r);
|
||||||
ap_rputs("</tr>\n", r);
|
ap_rputs(apr_strfsize(worker->s->read, fbuf), r);
|
||||||
|
ap_rputs("</td></tr>\n", r);
|
||||||
|
|
||||||
++worker;
|
++worker;
|
||||||
}
|
}
|
||||||
@@ -729,20 +738,22 @@ static int balancer_handler(request_rec *r)
|
|||||||
ap_rvputs(r, "<form method=\"GET\" action=\"", NULL);
|
ap_rvputs(r, "<form method=\"GET\" action=\"", NULL);
|
||||||
ap_rvputs(r, r->uri, "\">\n<dl>", NULL);
|
ap_rvputs(r, r->uri, "\">\n<dl>", NULL);
|
||||||
ap_rputs("<table><tr><td>Load factor:</td><td><input name=\"lf\" type=text ", r);
|
ap_rputs("<table><tr><td>Load factor:</td><td><input name=\"lf\" type=text ", r);
|
||||||
ap_rprintf(r, "value=\"%d\"></td><tr>\n", wsel->s->lbfactor);
|
ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbfactor);
|
||||||
|
ap_rputs("<tr><td>LB Set:</td><td><input name=\"ls\" type=text ", r);
|
||||||
|
ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbset);
|
||||||
ap_rputs("<tr><td>Route:</td><td><input name=\"wr\" type=text ", r);
|
ap_rputs("<tr><td>Route:</td><td><input name=\"wr\" type=text ", r);
|
||||||
ap_rvputs(r, "value=\"", wsel->route, NULL);
|
ap_rvputs(r, "value=\"", wsel->route, NULL);
|
||||||
ap_rputs("\"></td><tr>\n", r);
|
ap_rputs("\"></td></tr>\n", r);
|
||||||
ap_rputs("<tr><td>Route Redirect:</td><td><input name=\"rr\" type=text ", r);
|
ap_rputs("<tr><td>Route Redirect:</td><td><input name=\"rr\" type=text ", r);
|
||||||
ap_rvputs(r, "value=\"", wsel->redirect, NULL);
|
ap_rvputs(r, "value=\"", wsel->redirect, NULL);
|
||||||
ap_rputs("\"></td><tr>\n", r);
|
ap_rputs("\"></td></tr>\n", r);
|
||||||
ap_rputs("<tr><td>Status:</td><td>Disabled: <input name=\"dw\" value=\"Disable\" type=radio", r);
|
ap_rputs("<tr><td>Status:</td><td>Disabled: <input name=\"dw\" value=\"Disable\" type=radio", r);
|
||||||
if (wsel->s->status & PROXY_WORKER_DISABLED)
|
if (wsel->s->status & PROXY_WORKER_DISABLED)
|
||||||
ap_rputs(" checked", r);
|
ap_rputs(" checked", r);
|
||||||
ap_rputs("> | Enabled: <input name=\"dw\" value=\"Enable\" type=radio", r);
|
ap_rputs("> | Enabled: <input name=\"dw\" value=\"Enable\" type=radio", r);
|
||||||
if (!(wsel->s->status & PROXY_WORKER_DISABLED))
|
if (!(wsel->s->status & PROXY_WORKER_DISABLED))
|
||||||
ap_rputs(" checked", r);
|
ap_rputs(" checked", r);
|
||||||
ap_rputs("></td><tr>\n", r);
|
ap_rputs("></td></tr>\n", r);
|
||||||
ap_rputs("<tr><td colspan=2><input type=submit value=\"Submit\"></td></tr>\n", r);
|
ap_rputs("<tr><td colspan=2><input type=submit value=\"Submit\"></td></tr>\n", r);
|
||||||
ap_rvputs(r, "</table>\n<input type=hidden name=\"w\" ", NULL);
|
ap_rvputs(r, "</table>\n<input type=hidden name=\"w\" ", NULL);
|
||||||
ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->name), "\">\n", NULL);
|
ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->name), "\">\n", NULL);
|
||||||
@@ -867,37 +878,48 @@ static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
|
|||||||
proxy_worker *mycandidate = NULL;
|
proxy_worker *mycandidate = NULL;
|
||||||
int checking_standby = 0;
|
int checking_standby = 0;
|
||||||
int checked_standby = 0;
|
int checked_standby = 0;
|
||||||
|
int cur_lbset = 0;
|
||||||
|
int max_lbset = 0;
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
||||||
"proxy: Entering byrequests for BALANCER (%s)",
|
"proxy: Entering byrequests for BALANCER (%s)",
|
||||||
balancer->name);
|
balancer->name);
|
||||||
|
|
||||||
/* First try to see if we have available candidate */
|
/* First try to see if we have available candidate */
|
||||||
while (!mycandidate && !checked_standby) {
|
do {
|
||||||
worker = (proxy_worker *)balancer->workers->elts;
|
while (!mycandidate && !checked_standby) {
|
||||||
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
|
worker = (proxy_worker *)balancer->workers->elts;
|
||||||
if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
|
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
|
||||||
continue;
|
if (!checking_standby) { /* first time through */
|
||||||
/* If the worker is in error state run
|
if (worker->s->lbset > max_lbset)
|
||||||
* retry on that worker. It will be marked as
|
max_lbset = worker->s->lbset;
|
||||||
* operational if the retry timeout is elapsed.
|
}
|
||||||
* The worker might still be unusable, but we try
|
if (worker->s->lbset > cur_lbset)
|
||||||
* anyway.
|
continue;
|
||||||
*/
|
if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
|
||||||
if (!PROXY_WORKER_IS_USABLE(worker))
|
continue;
|
||||||
ap_proxy_retry_worker("BALANCER", worker, r->server);
|
/* If the worker is in error state run
|
||||||
/* Take into calculation only the workers that are
|
* retry on that worker. It will be marked as
|
||||||
* not in error state or not disabled.
|
* operational if the retry timeout is elapsed.
|
||||||
*/
|
* The worker might still be unusable, but we try
|
||||||
if (PROXY_WORKER_IS_USABLE(worker)) {
|
* anyway.
|
||||||
worker->s->lbstatus += worker->s->lbfactor;
|
*/
|
||||||
total_factor += worker->s->lbfactor;
|
if (!PROXY_WORKER_IS_USABLE(worker))
|
||||||
if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus)
|
ap_proxy_retry_worker("BALANCER", worker, r->server);
|
||||||
mycandidate = worker;
|
/* Take into calculation only the workers that are
|
||||||
|
* not in error state or not disabled.
|
||||||
|
*/
|
||||||
|
if (PROXY_WORKER_IS_USABLE(worker)) {
|
||||||
|
worker->s->lbstatus += worker->s->lbfactor;
|
||||||
|
total_factor += worker->s->lbfactor;
|
||||||
|
if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus)
|
||||||
|
mycandidate = worker;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
checked_standby = checking_standby++;
|
||||||
}
|
}
|
||||||
checked_standby = checking_standby++;
|
cur_lbset++;
|
||||||
}
|
} while (cur_lbset < max_lbset && !mycandidate);
|
||||||
|
|
||||||
if (mycandidate) {
|
if (mycandidate) {
|
||||||
mycandidate->s->lbstatus -= total_factor;
|
mycandidate->s->lbstatus -= total_factor;
|
||||||
@@ -934,39 +956,50 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
|
|||||||
int checking_standby = 0;
|
int checking_standby = 0;
|
||||||
int checked_standby = 0;
|
int checked_standby = 0;
|
||||||
proxy_worker *mycandidate = NULL;
|
proxy_worker *mycandidate = NULL;
|
||||||
|
int cur_lbset = 0;
|
||||||
|
int max_lbset = 0;
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
||||||
"proxy: Entering bytraffic for BALANCER (%s)",
|
"proxy: Entering bytraffic for BALANCER (%s)",
|
||||||
balancer->name);
|
balancer->name);
|
||||||
|
|
||||||
/* First try to see if we have available candidate */
|
/* First try to see if we have available candidate */
|
||||||
while (!mycandidate && !checked_standby) {
|
do {
|
||||||
worker = (proxy_worker *)balancer->workers->elts;
|
while (!mycandidate && !checked_standby) {
|
||||||
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
|
worker = (proxy_worker *)balancer->workers->elts;
|
||||||
if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
|
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
|
||||||
continue;
|
if (!checking_standby) { /* first time through */
|
||||||
/* If the worker is in error state run
|
if (worker->s->lbset > max_lbset)
|
||||||
* retry on that worker. It will be marked as
|
max_lbset = worker->s->lbset;
|
||||||
* operational if the retry timeout is elapsed.
|
}
|
||||||
* The worker might still be unusable, but we try
|
if (worker->s->lbset > cur_lbset)
|
||||||
* anyway.
|
continue;
|
||||||
*/
|
if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) )
|
||||||
if (!PROXY_WORKER_IS_USABLE(worker))
|
continue;
|
||||||
ap_proxy_retry_worker("BALANCER", worker, r->server);
|
/* If the worker is in error state run
|
||||||
/* Take into calculation only the workers that are
|
* retry on that worker. It will be marked as
|
||||||
* not in error state or not disabled.
|
* operational if the retry timeout is elapsed.
|
||||||
*/
|
* The worker might still be unusable, but we try
|
||||||
if (PROXY_WORKER_IS_USABLE(worker)) {
|
* anyway.
|
||||||
mytraffic = (worker->s->transferred/worker->s->lbfactor) +
|
*/
|
||||||
(worker->s->read/worker->s->lbfactor);
|
if (!PROXY_WORKER_IS_USABLE(worker))
|
||||||
if (!mycandidate || mytraffic < curmin) {
|
ap_proxy_retry_worker("BALANCER", worker, r->server);
|
||||||
mycandidate = worker;
|
/* Take into calculation only the workers that are
|
||||||
curmin = mytraffic;
|
* not in error state or not disabled.
|
||||||
|
*/
|
||||||
|
if (PROXY_WORKER_IS_USABLE(worker)) {
|
||||||
|
mytraffic = (worker->s->transferred/worker->s->lbfactor) +
|
||||||
|
(worker->s->read/worker->s->lbfactor);
|
||||||
|
if (!mycandidate || mytraffic < curmin) {
|
||||||
|
mycandidate = worker;
|
||||||
|
curmin = mytraffic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
checked_standby = checking_standby++;
|
||||||
}
|
}
|
||||||
checked_standby = checking_standby++;
|
cur_lbset++;
|
||||||
}
|
} while (cur_lbset < max_lbset && !mycandidate);
|
||||||
|
|
||||||
if (mycandidate) {
|
if (mycandidate) {
|
||||||
mycandidate->s->elected++;
|
mycandidate->s->elected++;
|
||||||
|
Reference in New Issue
Block a user