View | Details | Raw Unified | Return to bug 61140
Collapse All | Expand All

(-)a/docs/log-message-tags/next-number (-1 / +1 lines)
Line 1 Link Here
1
10033
1
10035
(-)a/docs/manual/howto/reverse_proxy.xml (-26 / +52 lines)
Lines 147-153 Link Here
147
147
148
    <note type="hint"><title>Hint</title>
148
    <note type="hint"><title>Hint</title>
149
      <p>
149
      <p>
150
      	<em>BalancerMembers</em> are also sometimes referred to as <em>workers</em>.
150
        <em>BalancerMembers</em> are also sometimes referred to as <em>workers</em>.
151
      </p>
151
      </p>
152
   </note>
152
   </note>
153
153
Lines 182-201 Link Here
182
    <title>Failover</title>
182
    <title>Failover</title>
183
183
184
    <p>
184
    <p>
185
      You can also fine-tune various failover scenarios, detailing which
185
      You can also fine-tune various failover scenarios, detailing which workers
186
      workers and even which balancers should accessed in such cases. For
186
      and even which balancers should accessed in such cases. For example, the
187
      example, the below setup implements 2 failover cases: In the first,
187
      below setup implements three failover cases:
188
      <code>http://hstandby.example.com:8080</code> is only sent traffic
188
    </p>
189
      if all other workers in the <em>myset</em> balancer are not available.
189
    <ol>
190
      If that worker itself is not available, only then will the
190
      <li>
191
      <code>http://bkup1.example.com:8080</code> and <code>http://bkup2.example.com:8080</code>
191
        <code>http://spare1.example.com:8080</code> and
192
      workers be brought into rotation:
192
        <code>http://spare2.example.com:8080</code> are only sent traffic if one
193
        or both of <code>http://www2.example.com:8080</code> or
194
        <code>http://www3.example.com:8080</code> is unavailable. (One spare
195
        will be used to replace one unusable member of the same balancer set.)
196
      </li>
197
      <li>
198
        <code>http://hstandby.example.com:8080</code> is only sent traffic if
199
        all other workers in balancer set <code>0</code> are not available.
200
      </li>
201
      <li>
202
        If all load balancer set <code>0</code> workers, spares, and the standby
203
        are unavailable, only then will the
204
        <code>http://bkup1.example.com:8080</code> and
205
        <code>http://bkup2.example.com:8080</code> workers from balancer set
206
        <code>1</code> be brought into rotation.
207
      </li>
208
    </ol>
209
    <p>
210
      Thus, it is possible to have one or more hot spares and hot standbys for
211
      each load balancer set.
193
    </p>
212
    </p>
194
213
195
    <highlight language="config">
214
    <highlight language="config">
196
&lt;Proxy balancer://myset&gt;
215
&lt;Proxy balancer://myset&gt;
197
    BalancerMember http://www2.example.com:8080
216
    BalancerMember http://www2.example.com:8080
198
    BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
217
    BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
218
    BalancerMember http://spare1.example.com:8080 status=+R
219
    BalancerMember http://spare2.example.com:8080 status=+R
199
    BalancerMember http://hstandby.example.com:8080 status=+H
220
    BalancerMember http://hstandby.example.com:8080 status=+H
200
    BalancerMember http://bkup1.example.com:8080 lbset=1
221
    BalancerMember http://bkup1.example.com:8080 lbset=1
201
    BalancerMember http://bkup2.example.com:8080 lbset=1
222
    BalancerMember http://bkup2.example.com:8080 lbset=1
Lines 207-217 Link Here
207
    </highlight>
228
    </highlight>
208
229
209
    <p>
230
    <p>
210
      The magic of this failover setup is setting <code>http://hstandby.example.com:8080</code>
231
      For failover, hot spares are used as replacements for unusable workers in
211
      with the <code>+H</code> status flag, which puts it in <em>hot standby</em> mode,
232
      the same load balancer set. A worker is considered unusable if it is
212
      and making the 2 <code>bkup#</code> servers part of the #1 load balancer set (the
233
      draining, stopped, or otherwise in an error/failed state. Hot standbys are
213
      default set is 0); for failover, hot standbys (if they exist) are used 1st, when all regular
234
      used if all workers and spares in the load balancer set are
214
      workers are unavailable; load balancer sets with lowest number are always tried first.
235
      unavailable. Load balancer sets (with their respective hot spares and
236
      standbys) are always tried in order from lowest to highest.
215
    </p>
237
    </p>
216
238
217
  </section>
239
  </section>
Lines 221-234 Link Here
221
243
222
    <p>
244
    <p>
223
      One of the most unique and useful features of Apache httpd's reverse proxy is
245
      One of the most unique and useful features of Apache httpd's reverse proxy is
224
	  the embedded <em>balancer-manager</em> application. Similar to
246
          the embedded <em>balancer-manager</em> application. Similar to
225
	  <module>mod_status</module>, <em>balancer-manager</em> displays
247
          <module>mod_status</module>, <em>balancer-manager</em> displays
226
	  the current working configuration and status of the enabled
248
          the current working configuration and status of the enabled
227
	  balancers and workers currently in use. However, not only does it
249
          balancers and workers currently in use. However, not only does it
228
	  display these parameters, it also allows for dynamic, runtime, on-the-fly
250
          display these parameters, it also allows for dynamic, runtime, on-the-fly
229
	  reconfiguration of almost all of them, including adding new <em>BalancerMembers</em>
251
          reconfiguration of almost all of them, including adding new <em>BalancerMembers</em>
230
	  (workers) to an existing balancer. To enable these capability, the following
252
          (workers) to an existing balancer. To enable these capability, the following
231
	  needs to be added to your configuration:
253
          needs to be added to your configuration:
232
    </p>
254
    </p>
233
255
234
    <highlight language="config">
256
    <highlight language="config">
Lines 293-308 Link Here
293
      is displayed and can be set/reset. The meanings of these statuses are as follows:
315
      is displayed and can be set/reset. The meanings of these statuses are as follows:
294
    </p>
316
    </p>
295
      <table border="1">
317
      <table border="1">
296
      	<tr><th>Flag</th><th>String</th><th>Description</th></tr>
318
        <tr><th>Flag</th><th>String</th><th>Description</th></tr>
297
      	<tr><td>&nbsp;</td><td><em>Ok</em></td><td>Worker is available</td></tr>
319
        <tr><td>&nbsp;</td><td><em>Ok</em></td><td>Worker is available</td></tr>
298
      	<tr><td>&nbsp;</td><td><em>Init</em></td><td>Worker has been initialized</td></tr>
320
        <tr><td>&nbsp;</td><td><em>Init</em></td><td>Worker has been initialized</td></tr>
299
        <tr><td><code>D</code></td><td><em>Dis</em></td><td>Worker is disabled and will not accept any requests; will be
321
        <tr><td><code>D</code></td><td><em>Dis</em></td><td>Worker is disabled and will not accept any requests; will be
300
                    automatically retried.</td></tr>
322
                    automatically retried.</td></tr>
301
        <tr><td><code>S</code></td><td><em>Stop</em></td><td>Worker is administratively stopped; will not accept requests
323
        <tr><td><code>S</code></td><td><em>Stop</em></td><td>Worker is administratively stopped; will not accept requests
302
                    and will not be automatically retried</td></tr>
324
                    and will not be automatically retried</td></tr>
303
        <tr><td><code>I</code></td><td><em>Ign</em></td><td>Worker is in ignore-errors mode and will always be considered available.</td></tr>
325
        <tr><td><code>I</code></td><td><em>Ign</em></td><td>Worker is in ignore-errors mode and will always be considered available.</td></tr>
326
        <tr><td><code>R</code></td><td><em>Spar</em></td><td>Worker is a hot spare. For each worker in a given lbset that is unusable
327
                    (draining, stopped, in error, etc.), a usable hot spare with the same lbset will be used in
328
                    its place. Hot spares can help ensure that a specific number of workers are always available
329
                    for use by a balancer.</td></tr>
304
        <tr><td><code>H</code></td><td><em>Stby</em></td><td>Worker is in hot-standby mode and will only be used if no other
330
        <tr><td><code>H</code></td><td><em>Stby</em></td><td>Worker is in hot-standby mode and will only be used if no other
305
                    viable workers are available.</td></tr>
331
                    viable workers or spares are available in the balancer set.</td></tr>
306
        <tr><td><code>E</code></td><td><em>Err</em></td><td>Worker is in an error state, usually due to failing pre-request check;
332
        <tr><td><code>E</code></td><td><em>Err</em></td><td>Worker is in an error state, usually due to failing pre-request check;
307
                    requests will not be proxied to this worker, but it will be retried depending on
333
                    requests will not be proxied to this worker, but it will be retried depending on
308
                    the <code>retry</code> setting of the worker.</td></tr>
334
                    the <code>retry</code> setting of the worker.</td></tr>
(-)a/docs/manual/mod/mod_proxy.xml (-9 / +29 lines)
Lines 306-315 Link Here
306
      <note><title>DNS resolution for origin domains</title>
306
      <note><title>DNS resolution for origin domains</title>
307
      <p>DNS resolution happens when the socket to
307
      <p>DNS resolution happens when the socket to
308
        the origin domain is created for the first time.
308
        the origin domain is created for the first time.
309
        When connection pooling is used, each backend domain is resolved 
309
        When connection pooling is used, each backend domain is resolved
310
        only once per child process, and reused for all further connections 
310
        only once per child process, and reused for all further connections
311
        until the child is recycled. This information should to be considered 
311
        until the child is recycled. This information should to be considered
312
        while planning DNS maintenance tasks involving backend domains. 
312
        while planning DNS maintenance tasks involving backend domains.
313
        Please also check <directive module="mod_proxy">ProxyPass</directive>
313
        Please also check <directive module="mod_proxy">ProxyPass</directive>
314
        parameters for more details about connection reuse.
314
        parameters for more details about connection reuse.
315
        </p>
315
        </p>
Lines 398-404 Link Here
398
&lt;/Location&gt;
398
&lt;/Location&gt;
399
        </highlight>
399
        </highlight>
400
400
401
      <p> In 2.4.26 and later, the "no-proxy" environment variable can be set to disable 
401
      <p> In 2.4.26 and later, the "no-proxy" environment variable can be set to disable
402
      <module>mod_proxy</module> processing the current request.
402
      <module>mod_proxy</module> processing the current request.
403
      This variable should be set with <directive module="mod_setenvif"
403
      This variable should be set with <directive module="mod_setenvif"
404
      >SetEnvIf</directive>, as <directive module="mod_env">SetEnv</directive>
404
      >SetEnvIf</directive>, as <directive module="mod_env">SetEnv</directive>
Lines 983-989 Link Here
983
      general <directive>ProxyPass</directive> directives. In 2.4.26 and later, the "no-proxy"
983
      general <directive>ProxyPass</directive> directives. In 2.4.26 and later, the "no-proxy"
984
      environment variable is an alternative to exclusions, and is the only
984
      environment variable is an alternative to exclusions, and is the only
985
      way to configure an exclusion of a <directive>ProxyPass</directive>
985
      way to configure an exclusion of a <directive>ProxyPass</directive>
986
      directive in <directive module="core">Location</directive> context. 
986
      directive in <directive module="core">Location</directive> context.
987
      This variable should be set with <directive module="mod_setenvif"
987
      This variable should be set with <directive module="mod_setenvif"
988
      >SetEnvIf</directive>, as <directive module="mod_env">SetEnv</directive>
988
      >SetEnvIf</directive>, as <directive module="mod_env">SetEnv</directive>
989
      is not evaluated early enough.
989
      is not evaluated early enough.
Lines 1180-1187 Link Here
1180
         <tr><td><code>S</code></td><td>Worker is administratively stopped; will not accept requests
1180
         <tr><td><code>S</code></td><td>Worker is administratively stopped; will not accept requests
1181
                    and will not be automatically retried</td></tr>
1181
                    and will not be automatically retried</td></tr>
1182
         <tr><td><code>I</code></td><td>Worker is in ignore-errors mode and will always be considered available.</td></tr>
1182
         <tr><td><code>I</code></td><td>Worker is in ignore-errors mode and will always be considered available.</td></tr>
1183
         <tr><td><code>R</code></td><td>Worker is a hot spare. For each worker in a given lbset that is unusable
1184
                    (draining, stopped, in error, etc.), a usable hot spare with the same lbset will be used in
1185
                    its place. Hot spares can help ensure that a specific number of workers are always available
1186
                    for use by a balancer.</td></tr>
1183
         <tr><td><code>H</code></td><td>Worker is in hot-standby mode and will only be used if no other
1187
         <tr><td><code>H</code></td><td>Worker is in hot-standby mode and will only be used if no other
1184
                    viable workers are available.</td></tr>
1188
                    viable workers or spares are available in the balancer set.</td></tr>
1185
         <tr><td><code>E</code></td><td>Worker is in an error state.</td></tr>
1189
         <tr><td><code>E</code></td><td>Worker is in an error state.</td></tr>
1186
         <tr><td><code>N</code></td><td>Worker is in drain mode and will only accept existing sticky sessions
1190
         <tr><td><code>N</code></td><td>Worker is in drain mode and will only accept existing sticky sessions
1187
                    destined for itself and ignore all other requests.</td></tr>
1191
                    destined for itself and ignore all other requests.</td></tr>
Lines 1335-1342 Link Here
1335
&lt;/Proxy&gt;
1339
&lt;/Proxy&gt;
1336
    </highlight>
1340
    </highlight>
1337
1341
1342
    <p>Configuring hot spares can help ensure that a certain number of
1343
    workers are always available for use per load balancer set:</p>
1344
    <highlight language="config">
1345
ProxyPass "/" "balancer://sparecluster/"
1346
&lt;Proxy balancer://sparecluster&gt;
1347
    BalancerMember ajp://1.2.3.4:8009
1348
    BalancerMember ajp://1.2.3.5:8009
1349
    # The servers below are hot spares. For each server above that is unusable
1350
    # (draining, stopped, unreachable, in error state, etc.), one of these spares
1351
    # will be used in its place. Two servers will always be available for a request
1352
    # unless one or more of the spares is also unusable.
1353
    BalancerMember ajp://1.2.3.6:8009 status=+R
1354
    BalancerMember ajp://1.2.3.7:8009 status=+R
1355
&lt;/Proxy&gt;
1356
    </highlight>
1357
1338
    <p>Setting up a hot-standby that will only be used if no other
1358
    <p>Setting up a hot-standby that will only be used if no other
1339
     members are available:</p>
1359
    members (or spares) are available in the load balancer set:</p>
1340
    <highlight language="config">
1360
    <highlight language="config">
1341
ProxyPass "/" "balancer://hotcluster/"
1361
ProxyPass "/" "balancer://hotcluster/"
1342
&lt;Proxy balancer://hotcluster&gt;
1362
&lt;Proxy balancer://hotcluster&gt;
Lines 1393-1399 Link Here
1393
<name>ProxyPassMatch</name>
1413
<name>ProxyPassMatch</name>
1394
<description>Maps remote servers into the local server URL-space using regular expressions</description>
1414
<description>Maps remote servers into the local server URL-space using regular expressions</description>
1395
<syntax>ProxyPassMatch [<var>regex</var>] !|<var>url</var> [<var>key=value</var>
1415
<syntax>ProxyPassMatch [<var>regex</var>] !|<var>url</var> [<var>key=value</var>
1396
	<var>[key=value</var> ...]]</syntax>
1416
        <var>[key=value</var> ...]]</syntax>
1397
<contextlist><context>server config</context><context>virtual host</context>
1417
<contextlist><context>server config</context><context>virtual host</context>
1398
<context>directory</context>
1418
<context>directory</context>
1399
</contextlist>
1419
</contextlist>
(-)a/modules/proxy/balancers/mod_lbmethod_bybusyness.c (-87 / +22 lines)
Lines 22-120 Link Here
22
22
23
module AP_MODULE_DECLARE_DATA lbmethod_bybusyness_module;
23
module AP_MODULE_DECLARE_DATA lbmethod_bybusyness_module;
24
24
25
static int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
25
static int is_best_bybusyness(proxy_worker *current, proxy_worker *prev_best, void *baton)
26
        proxy_worker *worker, server_rec *s) = NULL;
26
{
27
    int *total_factor = (int *)baton;
28
29
    current->s->lbstatus += current->s->lbfactor;
30
    *total_factor += current->s->lbfactor;
31
32
    return (
33
        !prev_best
34
        || (current->s->busy < prev_best->s->busy)
35
        || (
36
            (current->s->busy == prev_best->s->busy)
37
            && (current->s->lbstatus > prev_best->s->lbstatus)
38
        )
39
    );
40
}
27
41
28
static proxy_worker *find_best_bybusyness(proxy_balancer *balancer,
42
static proxy_worker *find_best_bybusyness(proxy_balancer *balancer,
29
                                request_rec *r)
43
                                          request_rec *r)
30
{
44
{
31
    int i;
45
    int total_factor = 0;
32
    proxy_worker **worker;
46
    proxy_worker *worker = ap_proxy_balancer_get_best_worker(balancer, r, is_best_bybusyness, &total_factor);
33
    proxy_worker *mycandidate = NULL;
34
    int cur_lbset = 0;
35
    int max_lbset = 0;
36
    int checking_standby;
37
    int checked_standby;
38
47
39
    int total_factor = 0;
48
    if (worker) {
40
49
        worker->s->lbstatus -= total_factor;
41
    if (!ap_proxy_retry_worker_fn) {
42
        ap_proxy_retry_worker_fn =
43
                APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker);
44
        if (!ap_proxy_retry_worker_fn) {
45
            /* can only happen if mod_proxy isn't loaded */
46
            return NULL;
47
        }
48
    }
50
    }
49
51
50
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01211)
52
    return worker;
51
                 "proxy: Entering bybusyness for BALANCER (%s)",
52
                 balancer->s->name);
53
54
    /* First try to see if we have available candidate */
55
    do {
56
57
        checking_standby = checked_standby = 0;
58
        while (!mycandidate && !checked_standby) {
59
60
            worker = (proxy_worker **)balancer->workers->elts;
61
            for (i = 0; i < balancer->workers->nelts; i++, worker++) {
62
                if  (!checking_standby) {    /* first time through */
63
                    if ((*worker)->s->lbset > max_lbset)
64
                        max_lbset = (*worker)->s->lbset;
65
                }
66
                if (
67
                    ((*worker)->s->lbset != cur_lbset) ||
68
                    (checking_standby ? !PROXY_WORKER_IS_STANDBY(*worker) : PROXY_WORKER_IS_STANDBY(*worker)) ||
69
                    (PROXY_WORKER_IS_DRAINING(*worker))
70
                    ) {
71
                    continue;
72
                }
73
74
                /* If the worker is in error state run
75
                 * retry on that worker. It will be marked as
76
                 * operational if the retry timeout is elapsed.
77
                 * The worker might still be unusable, but we try
78
                 * anyway.
79
                 */
80
                if (!PROXY_WORKER_IS_USABLE(*worker)) {
81
                    ap_proxy_retry_worker_fn("BALANCER", *worker, r->server);
82
                }
83
84
                /* Take into calculation only the workers that are
85
                 * not in error state or not disabled.
86
                 */
87
                if (PROXY_WORKER_IS_USABLE(*worker)) {
88
89
                    (*worker)->s->lbstatus += (*worker)->s->lbfactor;
90
                    total_factor += (*worker)->s->lbfactor;
91
92
                    if (!mycandidate
93
                        || (*worker)->s->busy < mycandidate->s->busy
94
                        || ((*worker)->s->busy == mycandidate->s->busy && (*worker)->s->lbstatus > mycandidate->s->lbstatus))
95
                        mycandidate = *worker;
96
97
                }
98
99
            }
100
101
            checked_standby = checking_standby++;
102
103
        }
104
105
        cur_lbset++;
106
107
    } while (cur_lbset <= max_lbset && !mycandidate);
108
109
    if (mycandidate) {
110
        mycandidate->s->lbstatus -= total_factor;
111
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01212)
112
                     "proxy: bybusyness selected worker \"%s\" : busy %" APR_SIZE_T_FMT " : lbstatus %d",
113
                     mycandidate->s->name, mycandidate->s->busy, mycandidate->s->lbstatus);
114
115
    }
116
117
    return mycandidate;
118
}
53
}
119
54
120
/* assumed to be mutex protected by caller */
55
/* assumed to be mutex protected by caller */
(-)a/modules/proxy/balancers/mod_lbmethod_byrequests.c (-72 / +14 lines)
Lines 22-29 Link Here
22
22
23
module AP_MODULE_DECLARE_DATA lbmethod_byrequests_module;
23
module AP_MODULE_DECLARE_DATA lbmethod_byrequests_module;
24
24
25
static int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
25
static int is_best_byrequests(proxy_worker *current, proxy_worker *prev_best, void *baton)
26
        proxy_worker *worker, server_rec *s) = NULL;
26
{
27
    int *total_factor = (int *)baton;
28
29
    current->s->lbstatus += current->s->lbfactor;
30
    *total_factor += current->s->lbfactor;
31
32
    return (!prev_best || (current->s->lbstatus > prev_best->s->lbstatus));
33
}
27
34
28
/*
35
/*
29
 * The idea behind the find_best_byrequests scheduler is the following:
36
 * The idea behind the find_best_byrequests scheduler is the following:
Lines 70-151 Link Here
70
 *   b a d c d a c d b d ...
77
 *   b a d c d a c d b d ...
71
 *
78
 *
72
 */
79
 */
73
74
static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
80
static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
75
                                request_rec *r)
81
                                          request_rec *r)
76
{
82
{
77
    int i;
78
    int total_factor = 0;
83
    int total_factor = 0;
79
    proxy_worker **worker;
84
    proxy_worker *worker = ap_proxy_balancer_get_best_worker(balancer, r, is_best_byrequests, &total_factor);
80
    proxy_worker *mycandidate = NULL;
81
    int cur_lbset = 0;
82
    int max_lbset = 0;
83
    int checking_standby;
84
    int checked_standby;
85
85
86
    if (!ap_proxy_retry_worker_fn) {
86
    if (worker) {
87
        ap_proxy_retry_worker_fn =
87
        worker->s->lbstatus -= total_factor;
88
                APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker);
89
        if (!ap_proxy_retry_worker_fn) {
90
            /* can only happen if mod_proxy isn't loaded */
91
            return NULL;
92
        }
93
    }
88
    }
94
89
95
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01207)
90
    return worker;
96
                 "proxy: Entering byrequests for BALANCER (%s)",
97
                 balancer->s->name);
98
99
    /* First try to see if we have available candidate */
100
    do {
101
        checking_standby = checked_standby = 0;
102
        while (!mycandidate && !checked_standby) {
103
            worker = (proxy_worker **)balancer->workers->elts;
104
            for (i = 0; i < balancer->workers->nelts; i++, worker++) {
105
                if (!checking_standby) {    /* first time through */
106
                    if ((*worker)->s->lbset > max_lbset)
107
                        max_lbset = (*worker)->s->lbset;
108
                }
109
                if (
110
                    ((*worker)->s->lbset != cur_lbset) ||
111
                    (checking_standby ? !PROXY_WORKER_IS_STANDBY(*worker) : PROXY_WORKER_IS_STANDBY(*worker)) ||
112
                    (PROXY_WORKER_IS_DRAINING(*worker))
113
                    ) {
114
                    continue;
115
                }
116
117
                /* If the worker is in error state run
118
                 * retry on that worker. It will be marked as
119
                 * operational if the retry timeout is elapsed.
120
                 * The worker might still be unusable, but we try
121
                 * anyway.
122
                 */
123
                if (!PROXY_WORKER_IS_USABLE(*worker))
124
                    ap_proxy_retry_worker_fn("BALANCER", *worker, r->server);
125
                /* Take into calculation only the workers that are
126
                 * not in error state or not disabled.
127
                 */
128
                if (PROXY_WORKER_IS_USABLE(*worker)) {
129
                    (*worker)->s->lbstatus += (*worker)->s->lbfactor;
130
                    total_factor += (*worker)->s->lbfactor;
131
                    if (!mycandidate || (*worker)->s->lbstatus > mycandidate->s->lbstatus)
132
                        mycandidate = *worker;
133
                }
134
            }
135
            checked_standby = checking_standby++;
136
        }
137
        cur_lbset++;
138
    } while (cur_lbset <= max_lbset && !mycandidate);
139
140
    if (mycandidate) {
141
        mycandidate->s->lbstatus -= total_factor;
142
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01208)
143
                     "proxy: byrequests selected worker \"%s\" : busy %" APR_SIZE_T_FMT " : lbstatus %d",
144
                     mycandidate->s->name, mycandidate->s->busy, mycandidate->s->lbstatus);
145
146
    }
147
148
    return mycandidate;
149
}
91
}
150
92
151
/* assumed to be mutex protected by caller */
93
/* assumed to be mutex protected by caller */
(-)a/modules/proxy/balancers/mod_lbmethod_bytraffic.c (-74 / +16 lines)
Lines 22-29 Link Here
22
22
23
module AP_MODULE_DECLARE_DATA lbmethod_bytraffic_module;
23
module AP_MODULE_DECLARE_DATA lbmethod_bytraffic_module;
24
24
25
static int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
25
static int is_best_bytraffic(proxy_worker *current, proxy_worker *prev_best, void *baton)
26
        proxy_worker *worker, server_rec *s) = NULL;
26
{
27
    apr_off_t *min_traffic = (apr_off_t *)baton;
28
    apr_off_t traffic = (current->s->transferred / current->s->lbfactor)
29
                        + (current->s->read / current->s->lbfactor);
30
31
    if (!prev_best || (traffic < *min_traffic)) {
32
        *min_traffic = traffic;
33
34
        return TRUE;
35
    }
36
37
    return FALSE;
38
}
27
39
28
/*
40
/*
29
 * The idea behind the find_best_bytraffic scheduler is the following:
41
 * The idea behind the find_best_bytraffic scheduler is the following:
Lines 45-123 Link Here
45
static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
57
static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
46
                                         request_rec *r)
58
                                         request_rec *r)
47
{
59
{
48
    int i;
60
    apr_off_t min_traffic = 0;
49
    apr_off_t mytraffic = 0;
50
    apr_off_t curmin = 0;
51
    proxy_worker **worker;
52
    proxy_worker *mycandidate = NULL;
53
    int cur_lbset = 0;
54
    int max_lbset = 0;
55
    int checking_standby;
56
    int checked_standby;
57
58
    if (!ap_proxy_retry_worker_fn) {
59
        ap_proxy_retry_worker_fn =
60
                APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker);
61
        if (!ap_proxy_retry_worker_fn) {
62
            /* can only happen if mod_proxy isn't loaded */
63
            return NULL;
64
        }
65
    }
66
67
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01209)
68
                 "proxy: Entering bytraffic for BALANCER (%s)",
69
                 balancer->s->name);
70
61
71
    /* First try to see if we have available candidate */
62
    return ap_proxy_balancer_get_best_worker(balancer, r, is_best_bytraffic, &min_traffic);
72
    do {
73
        checking_standby = checked_standby = 0;
74
        while (!mycandidate && !checked_standby) {
75
            worker = (proxy_worker **)balancer->workers->elts;
76
            for (i = 0; i < balancer->workers->nelts; i++, worker++) {
77
                if (!checking_standby) {    /* first time through */
78
                    if ((*worker)->s->lbset > max_lbset)
79
                        max_lbset = (*worker)->s->lbset;
80
                }
81
                if (
82
                    ((*worker)->s->lbset != cur_lbset) ||
83
                    (checking_standby ? !PROXY_WORKER_IS_STANDBY(*worker) : PROXY_WORKER_IS_STANDBY(*worker)) ||
84
                    (PROXY_WORKER_IS_DRAINING(*worker))
85
                    ) {
86
                    continue;
87
                }
88
89
                /* If the worker is in error state run
90
                 * retry on that worker. It will be marked as
91
                 * operational if the retry timeout is elapsed.
92
                 * The worker might still be unusable, but we try
93
                 * anyway.
94
                 */
95
                if (!PROXY_WORKER_IS_USABLE(*worker))
96
                    ap_proxy_retry_worker_fn("BALANCER", *worker, r->server);
97
                /* Take into calculation only the workers that are
98
                 * not in error state or not disabled.
99
                 */
100
                if (PROXY_WORKER_IS_USABLE(*worker)) {
101
                    mytraffic = ((*worker)->s->transferred/(*worker)->s->lbfactor) +
102
                                ((*worker)->s->read/(*worker)->s->lbfactor);
103
                    if (!mycandidate || mytraffic < curmin) {
104
                        mycandidate = *worker;
105
                        curmin = mytraffic;
106
                    }
107
                }
108
            }
109
            checked_standby = checking_standby++;
110
        }
111
        cur_lbset++;
112
    } while (cur_lbset <= max_lbset && !mycandidate);
113
114
    if (mycandidate) {
115
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01210)
116
                     "proxy: bytraffic selected worker \"%s\" : busy %" APR_SIZE_T_FMT,
117
                     mycandidate->s->name, mycandidate->s->busy);
118
    }
119
120
    return mycandidate;
121
}
63
}
122
64
123
/* assumed to be mutex protected by caller */
65
/* assumed to be mutex protected by caller */
(-)a/modules/proxy/mod_proxy.c (-5 / +5 lines)
Lines 68-73 Link Here
68
    {PROXY_WORKER_STOPPED,       PROXY_WORKER_STOPPED_FLAG,       "Stop "},
68
    {PROXY_WORKER_STOPPED,       PROXY_WORKER_STOPPED_FLAG,       "Stop "},
69
    {PROXY_WORKER_IN_ERROR,      PROXY_WORKER_IN_ERROR_FLAG,      "Err "},
69
    {PROXY_WORKER_IN_ERROR,      PROXY_WORKER_IN_ERROR_FLAG,      "Err "},
70
    {PROXY_WORKER_HOT_STANDBY,   PROXY_WORKER_HOT_STANDBY_FLAG,   "Stby "},
70
    {PROXY_WORKER_HOT_STANDBY,   PROXY_WORKER_HOT_STANDBY_FLAG,   "Stby "},
71
    {PROXY_WORKER_HOT_SPARE,     PROXY_WORKER_HOT_SPARE_FLAG,     "Spar "},
71
    {PROXY_WORKER_FREE,          PROXY_WORKER_FREE_FLAG,          "Free "},
72
    {PROXY_WORKER_FREE,          PROXY_WORKER_FREE_FLAG,          "Free "},
72
    {PROXY_WORKER_HC_FAIL,       PROXY_WORKER_HC_FAIL_FLAG,       "HcFl "},
73
    {PROXY_WORKER_HC_FAIL,       PROXY_WORKER_HC_FAIL_FLAG,       "HcFl "},
73
    {0x0, '\0', NULL}
74
    {0x0, '\0', NULL}
Lines 365-371 Link Here
365
        if (strlen(val) != 1) {
366
        if (strlen(val) != 1) {
366
            if (!strcasecmp(val, "off"))
367
            if (!strcasecmp(val, "off"))
367
                balancer->s->sticky_separator = 0;
368
                balancer->s->sticky_separator = 0;
368
            else      
369
            else
369
                return "stickysessionsep must be a single character or Off";
370
                return "stickysessionsep must be a single character or Off";
370
        }
371
        }
371
        else
372
        else
Lines 787-794 Link Here
787
        || !r->uri || r->uri[0] != '/') {
788
        || !r->uri || r->uri[0] != '/') {
788
        return DECLINED;
789
        return DECLINED;
789
    }
790
    }
790
   
791
791
    if (apr_table_get(r->subprocess_env, "no-proxy")) { 
792
    if (apr_table_get(r->subprocess_env, "no-proxy")) {
792
        return DECLINED;
793
        return DECLINED;
793
    }
794
    }
794
795
Lines 1292-1298 Link Here
1292
1293
1293
    if (DECLINED == access_status) {
1294
    if (DECLINED == access_status) {
1294
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01144)
1295
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01144)
1295
                      "No protocol handler was valid for the URL %s " 
1296
                      "No protocol handler was valid for the URL %s "
1296
                      "(scheme '%s'). "
1297
                      "(scheme '%s'). "
1297
                      "If you are using a DSO version of mod_proxy, make sure "
1298
                      "If you are using a DSO version of mod_proxy, make sure "
1298
                      "the proxy submodules are included in the configuration "
1299
                      "the proxy submodules are included in the configuration "
Lines 3114-3117 Link Here
3114
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, detach_backend,
3115
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, detach_backend,
3115
                                    (request_rec *r, proxy_conn_rec *backend),
3116
                                    (request_rec *r, proxy_conn_rec *backend),
3116
                                    (r, backend), OK, DECLINED)
3117
                                    (r, backend), OK, DECLINED)
3117
(-)a/modules/proxy/mod_proxy.h (-2 / +23 lines)
Lines 306-311 Link Here
306
#define PROXY_WORKER_HOT_STANDBY    0x0100
306
#define PROXY_WORKER_HOT_STANDBY    0x0100
307
#define PROXY_WORKER_FREE           0x0200
307
#define PROXY_WORKER_FREE           0x0200
308
#define PROXY_WORKER_HC_FAIL        0x0400
308
#define PROXY_WORKER_HC_FAIL        0x0400
309
#define PROXY_WORKER_HOT_SPARE      0x0800
309
310
310
/* worker status flags */
311
/* worker status flags */
311
#define PROXY_WORKER_INITIALIZED_FLAG    'O'
312
#define PROXY_WORKER_INITIALIZED_FLAG    'O'
Lines 319-324 Link Here
319
#define PROXY_WORKER_HOT_STANDBY_FLAG    'H'
320
#define PROXY_WORKER_HOT_STANDBY_FLAG    'H'
320
#define PROXY_WORKER_FREE_FLAG           'F'
321
#define PROXY_WORKER_FREE_FLAG           'F'
321
#define PROXY_WORKER_HC_FAIL_FLAG        'C'
322
#define PROXY_WORKER_HC_FAIL_FLAG        'C'
323
#define PROXY_WORKER_HOT_SPARE_FLAG      'R'
322
324
323
#define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
325
#define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
324
PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR | \
326
PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR | \
Lines 329-334 Link Here
329
331
330
#define PROXY_WORKER_IS_STANDBY(f)   ( (f)->s->status &  PROXY_WORKER_HOT_STANDBY )
332
#define PROXY_WORKER_IS_STANDBY(f)   ( (f)->s->status &  PROXY_WORKER_HOT_STANDBY )
331
333
334
#define PROXY_WORKER_IS_SPARE(f)   ( (f)->s->status &  PROXY_WORKER_HOT_SPARE )
335
332
#define PROXY_WORKER_IS_USABLE(f)   ( ( !( (f)->s->status & PROXY_WORKER_NOT_USABLE_BITMAP) ) && \
336
#define PROXY_WORKER_IS_USABLE(f)   ( ( !( (f)->s->status & PROXY_WORKER_NOT_USABLE_BITMAP) ) && \
333
  PROXY_WORKER_IS_INITIALIZED(f) )
337
  PROXY_WORKER_IS_INITIALIZED(f) )
334
338
Lines 503-509 Link Here
503
    char      sticky_separator;                                /* separator for sessionid/route */
507
    char      sticky_separator;                                /* separator for sessionid/route */
504
    unsigned int    forcerecovery_set:1;
508
    unsigned int    forcerecovery_set:1;
505
    unsigned int    scolonsep_set:1;
509
    unsigned int    scolonsep_set:1;
506
    unsigned int    sticky_force_set:1; 
510
    unsigned int    sticky_force_set:1;
507
    unsigned int    nonce_set:1;
511
    unsigned int    nonce_set:1;
508
    unsigned int    sticky_separator_set:1;
512
    unsigned int    sticky_separator_set:1;
509
} proxy_balancer_shared;
513
} proxy_balancer_shared;
Lines 665-671 Link Here
665
 * @param addr      resolved address of hostname, or NULL if not known
669
 * @param addr      resolved address of hostname, or NULL if not known
666
 * @return OK on success, or else an errro
670
 * @return OK on success, or else an errro
667
 */
671
 */
668
PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, 
672
PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf,
669
                                            const char *hostname, apr_sockaddr_t *addr);
673
                                            const char *hostname, apr_sockaddr_t *addr);
670
674
671
675
Lines 856-861 Link Here
856
                                                         server_rec *s,
860
                                                         server_rec *s,
857
                                                         apr_pool_t *p);
861
                                                         apr_pool_t *p);
858
862
863
typedef int (proxy_is_best_callback_fn_t)(proxy_worker *current, proxy_worker *prev_best, void *baton);
864
865
/**
866
 * Retrieve the best worker in a balancer for the current request
867
 * @param balancer balancer for which to find the best worker
868
 * @param r        current request record
869
 * @param is_best  a callback function provide by the lbmethod
870
 *                 that determines if the current worker is best
871
 * @param baton    an lbmethod-specific context pointer (baton)
872
 *                 passed to the is_best callback
873
 * @return         the best worker to be used for the request
874
 */
875
PROXY_DECLARE(proxy_worker *) ap_proxy_balancer_get_best_worker(proxy_balancer *balancer,
876
                                                                request_rec *r,
877
                                                                proxy_is_best_callback_fn_t *is_best,
878
                                                                void *baton);
879
859
/**
880
/**
860
 * Find the shm of the worker as needed
881
 * Find the shm of the worker as needed
861
 * @param storage slotmem provider
882
 * @param storage slotmem provider
(-)a/modules/proxy/mod_proxy_balancer.c (-3 / +8 lines)
Lines 312-318 Link Here
312
    /*
312
    /*
313
     * If we found a value for stickysession, find the first '.' (or whatever
313
     * If we found a value for stickysession, find the first '.' (or whatever
314
     * sticky_separator is set to) within. Everything after '.' (if present)
314
     * sticky_separator is set to) within. Everything after '.' (if present)
315
     * is our route. 
315
     * is our route.
316
     */
316
     */
317
    if ((*route) && (balancer->s->sticky_separator != 0) && ((*route = strchr(*route, balancer->s->sticky_separator)) != NULL ))
317
    if ((*route) && (balancer->s->sticky_separator != 0) && ((*route = strchr(*route, balancer->s->sticky_separator)) != NULL ))
318
        (*route)++;
318
        (*route)++;
Lines 458-464 Link Here
458
static apr_status_t decrement_busy_count(void *worker_)
458
static apr_status_t decrement_busy_count(void *worker_)
459
{
459
{
460
    proxy_worker *worker = worker_;
460
    proxy_worker *worker = worker_;
461
    
461
462
    if (worker->s->busy) {
462
    if (worker->s->busy) {
463
        worker->s->busy--;
463
        worker->s->busy--;
464
    }
464
    }
Lines 1127-1132 Link Here
1127
        if ((val = apr_table_get(params, "w_status_H"))) {
1127
        if ((val = apr_table_get(params, "w_status_H"))) {
1128
            ap_proxy_set_wstatus(PROXY_WORKER_HOT_STANDBY_FLAG, atoi(val), wsel);
1128
            ap_proxy_set_wstatus(PROXY_WORKER_HOT_STANDBY_FLAG, atoi(val), wsel);
1129
        }
1129
        }
1130
        if ((val = apr_table_get(params, "w_status_R"))) {
1131
            ap_proxy_set_wstatus(PROXY_WORKER_HOT_SPARE_FLAG, atoi(val), wsel);
1132
        }
1130
        if ((val = apr_table_get(params, "w_status_S"))) {
1133
        if ((val = apr_table_get(params, "w_status_S"))) {
1131
            ap_proxy_set_wstatus(PROXY_WORKER_STOPPED_FLAG, atoi(val), wsel);
1134
            ap_proxy_set_wstatus(PROXY_WORKER_STOPPED_FLAG, atoi(val), wsel);
1132
        }
1135
        }
Lines 1651-1657 Link Here
1651
                     "<th>Ignore Errors</th>"
1654
                     "<th>Ignore Errors</th>"
1652
                     "<th>Draining Mode</th>"
1655
                     "<th>Draining Mode</th>"
1653
                     "<th>Disabled</th>"
1656
                     "<th>Disabled</th>"
1654
                     "<th>Hot Standby</th>", r);
1657
                     "<th>Hot Standby</th>"
1658
                     "<th>Hot Spare</th>", r);
1655
            if (hc_show_exprs_f) {
1659
            if (hc_show_exprs_f) {
1656
                ap_rputs("<th>HC Fail</th>", r);
1660
                ap_rputs("<th>HC Fail</th>", r);
1657
            }
1661
            }
Lines 1660-1665 Link Here
1660
            create_radio("w_status_N", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DRAIN)), r);
1664
            create_radio("w_status_N", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DRAIN)), r);
1661
            create_radio("w_status_D", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DISABLED)), r);
1665
            create_radio("w_status_D", (PROXY_WORKER_IS(wsel, PROXY_WORKER_DISABLED)), r);
1662
            create_radio("w_status_H", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HOT_STANDBY)), r);
1666
            create_radio("w_status_H", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HOT_STANDBY)), r);
1667
            create_radio("w_status_R", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HOT_SPARE)), r);
1663
            if (hc_show_exprs_f) {
1668
            if (hc_show_exprs_f) {
1664
                create_radio("w_status_C", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HC_FAIL)), r);
1669
                create_radio("w_status_C", (PROXY_WORKER_IS(wsel, PROXY_WORKER_HC_FAIL)), r);
1665
            }
1670
            }
(-)a/modules/proxy/proxy_util.c (-5 / +121 lines)
Lines 66-71 Link Here
66
static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
66
static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
67
static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
67
static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
68
static int proxy_match_word(struct dirconn_entry *This, request_rec *r);
68
static int proxy_match_word(struct dirconn_entry *This, request_rec *r);
69
static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worker, server_rec *s);
69
70
70
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, create_req,
71
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, create_req,
71
                                   (request_rec *r, request_rec *pr), (r, pr),
72
                                   (request_rec *r, request_rec *pr), (r, pr),
Lines 1291-1296 Link Here
1291
    return APR_SUCCESS;
1292
    return APR_SUCCESS;
1292
}
1293
}
1293
1294
1295
PROXY_DECLARE(proxy_worker *) ap_proxy_balancer_get_best_worker(proxy_balancer *balancer,
1296
                                                                request_rec *r,
1297
                                                                proxy_is_best_callback_fn_t *is_best,
1298
                                                                void *baton)
1299
{
1300
    int i = 0;
1301
    int cur_lbset = 0;
1302
    int max_lbset = 0;
1303
    int unusable_workers = 0;
1304
    apr_pool_t *tpool = NULL;
1305
    apr_array_header_t *spares = NULL;
1306
    apr_array_header_t *standbys = NULL;
1307
    proxy_worker *worker = NULL;
1308
    proxy_worker *best_worker = NULL;
1309
1310
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(10033)
1311
                 "proxy: Entering %s for BALANCER (%s)",
1312
                 balancer->lbmethod->name, balancer->s->name);
1313
1314
    apr_pool_create(&tpool, r->pool);
1315
1316
    spares = apr_array_make(tpool, 1, sizeof(proxy_worker*));
1317
    standbys = apr_array_make(tpool, 1, sizeof(proxy_worker*));
1318
1319
    /* Process lbsets in order, only replacing unusable workers in a given lbset
1320
     * with available spares from the same lbset. Hot standbys will be used as a
1321
     * last resort when all other workers and spares are unavailable.
1322
     */
1323
    for (cur_lbset = 0; !best_worker && (cur_lbset <= max_lbset); cur_lbset++) {
1324
        unusable_workers = 0;
1325
        apr_array_clear(spares);
1326
        apr_array_clear(standbys);
1327
1328
        for (i = 0; i < balancer->workers->nelts; i++) {
1329
            worker = APR_ARRAY_IDX(balancer->workers, i, proxy_worker *);
1330
1331
            if (worker->s->lbset > max_lbset) {
1332
                max_lbset = worker->s->lbset;
1333
            }
1334
1335
            if (worker->s->lbset != cur_lbset) {
1336
                continue;
1337
            }
1338
1339
            /* A draining worker that is neither a spare nor a standby should be
1340
             * considered unusable to be replaced by spares.
1341
             */
1342
            if (PROXY_WORKER_IS_DRAINING(worker)) {
1343
                if (!PROXY_WORKER_IS_SPARE(worker) && !PROXY_WORKER_IS_STANDBY(worker)) {
1344
                    unusable_workers++;
1345
                }
1346
1347
                continue;
1348
            }
1349
1350
            /* If the worker is in error state run retry on that worker. It will
1351
             * be marked as operational if the retry timeout is elapsed.  The
1352
             * worker might still be unusable, but we try anyway.
1353
             */
1354
            if (!PROXY_WORKER_IS_USABLE(worker)) {
1355
                ap_proxy_retry_worker("BALANCER", worker, r->server);
1356
            }
1357
1358
            if (PROXY_WORKER_IS_SPARE(worker)) {
1359
                if (PROXY_WORKER_IS_USABLE(worker)) {
1360
                    APR_ARRAY_PUSH(spares, proxy_worker *) = worker;
1361
                }
1362
            }
1363
            else if (PROXY_WORKER_IS_STANDBY(worker)) {
1364
                if (PROXY_WORKER_IS_USABLE(worker)) {
1365
                    APR_ARRAY_PUSH(standbys, proxy_worker *) = worker;
1366
                }
1367
            }
1368
            else if (PROXY_WORKER_IS_USABLE(worker)) {
1369
              if (is_best(worker, best_worker, baton)) {
1370
                best_worker = worker;
1371
              }
1372
            }
1373
            else {
1374
                unusable_workers++;
1375
            }
1376
        }
1377
1378
        /* Check if any spares are best. */
1379
        for (i = 0; (i < spares->nelts) && (i < unusable_workers); i++) {
1380
          worker = APR_ARRAY_IDX(spares, i, proxy_worker *);
1381
1382
          if (is_best(worker, best_worker, baton)) {
1383
            best_worker = worker;
1384
          }
1385
        }
1386
1387
        /* If no workers are available, use the standbys. */
1388
        if (!best_worker) {
1389
            for (i = 0; i < standbys->nelts; i++) {
1390
              worker = APR_ARRAY_IDX(standbys, i, proxy_worker *);
1391
1392
              if (is_best(worker, best_worker, baton)) {
1393
                best_worker = worker;
1394
              }
1395
            }
1396
        }
1397
    }
1398
1399
    apr_pool_destroy(tpool);
1400
1401
    if (best_worker) {
1402
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(10034)
1403
                     "proxy: %s selected worker \"%s\" : busy %" APR_SIZE_T_FMT " : lbstatus %d",
1404
                     balancer->lbmethod->name, best_worker->s->name, best_worker->s->busy, best_worker->s->lbstatus);
1405
    }
1406
1407
    return best_worker;
1408
}
1409
1294
/*
1410
/*
1295
 * CONNECTION related...
1411
 * CONNECTION related...
1296
 */
1412
 */
Lines 1976-1984 Link Here
1976
/*
2092
/*
1977
 * In the case of the reverse proxy, we need to see if we
2093
 * In the case of the reverse proxy, we need to see if we
1978
 * were passed a UDS url (eg: from mod_proxy) and adjust uds_path
2094
 * were passed a UDS url (eg: from mod_proxy) and adjust uds_path
1979
 * as required.  
2095
 * as required.
1980
 */
2096
 */
1981
static void fix_uds_filename(request_rec *r, char **url) 
2097
static void fix_uds_filename(request_rec *r, char **url)
1982
{
2098
{
1983
    char *ptr, *ptr2;
2099
    char *ptr, *ptr2;
1984
    if (!r || !r->filename) return;
2100
    if (!r || !r->filename) return;
Lines 2289-2297 Link Here
2289
     * Figure out if our passed in proxy_conn_rec has a usable
2405
     * Figure out if our passed in proxy_conn_rec has a usable
2290
     * address cached.
2406
     * address cached.
2291
     *
2407
     *
2292
     * TODO: Handle this much better... 
2408
     * TODO: Handle this much better...
2293
     *
2409
     *
2294
     * XXX: If generic workers are ever address-reusable, we need 
2410
     * XXX: If generic workers are ever address-reusable, we need
2295
     *      to check host and port on the conn and be careful about
2411
     *      to check host and port on the conn and be careful about
2296
     *      spilling the cached addr from the worker.
2412
     *      spilling the cached addr from the worker.
2297
     */
2413
     */
Lines 2432-2438 Link Here
2432
    }
2548
    }
2433
2549
2434
    /* check if ProxyBlock directive on this host */
2550
    /* check if ProxyBlock directive on this host */
2435
    if (OK != ap_proxy_checkproxyblock(r, conf, uri->hostname, 
2551
    if (OK != ap_proxy_checkproxyblock(r, conf, uri->hostname,
2436
                                       proxyname ? NULL : conn->addr)) {
2552
                                       proxyname ? NULL : conn->addr)) {
2437
        return ap_proxyerror(r, HTTP_FORBIDDEN,
2553
        return ap_proxyerror(r, HTTP_FORBIDDEN,
2438
                             "Connect to remote machine blocked");
2554
                             "Connect to remote machine blocked");

Return to bug 61140