ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova/* Licensed to the Apache Software Foundation (ASF) under one or more
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * contributor license agreements. See the NOTICE file distributed with
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * this work for additional information regarding copyright ownership.
b43458b4d81f7451112cecbd757f3a05216e7088Kristina Sojakova * The ASF licenses this file to You under the Apache License, Version 2.0
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * (the "License"); you may not use this file except in compliance with
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * the License. You may obtain a copy of the License at
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * http://www.apache.org/licenses/LICENSE-2.0
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * Unless required by applicable law or agreed to in writing, software
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * distributed under the License is distributed on an "AS IS" BASIS,
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * See the License for the specific language governing permissions and
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * limitations under the License.
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakovamodule AP_MODULE_DECLARE_DATA lbmethod_byrequests_module;
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakovastatic int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
d2786879b4733fd4886a5b654f7c6de1d234f638Kristina Sojakova proxy_worker *worker, server_rec *s) = NULL;
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * The idea behind the find_best_byrequests scheduler is the following:
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * lbfactor is "how much we expect this worker to work", or "the worker's
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * normalized work quota".
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * lbstatus is "how urgent this worker has to work to fulfill its quota
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * We distribute each worker's work quota to the worker, and then look
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * which of them needs to work most urgently (biggest lbstatus). This
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * worker is then selected for work, and its lbstatus reduced by the
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * total work quota we distributed to all workers. Thus the sum of all
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * lbstatus does not change.(*)
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * If some workers are disabled, the others will
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * still be scheduled correctly.
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * If a balancer is configured as follows:
14650c9e129d8dc51ed55b2edc6ec27d9f0f6d00Kristina Sojakova * worker a b c d
d2786879b4733fd4886a5b654f7c6de1d234f638Kristina Sojakova * lbfactor 25 25 25 25
d2786879b4733fd4886a5b654f7c6de1d234f638Kristina Sojakova * And b gets disabled, the following schedule is produced:
d2786879b4733fd4886a5b654f7c6de1d234f638Kristina Sojakova * a c d a c d a c d ...
d2786879b4733fd4886a5b654f7c6de1d234f638Kristina Sojakova * Note that the above lbfactor setting is the *exact* same as:
b43458b4d81f7451112cecbd757f3a05216e7088Kristina Sojakova * worker a b c d
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * lbfactor 1 1 1 1
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * Asymmetric configurations work as one would expect. For
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * worker a b c d
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * lbfactor 1 1 1 2
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * would have a, b and c all handling about the same
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova * amount of load with d handling twice what a or b
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova * or c handles individually. So we could see:
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova * b a d c d a c d b d ...
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakovastatic proxy_worker *find_best_byrequests(proxy_balancer *balancer,
d2786879b4733fd4886a5b654f7c6de1d234f638Kristina Sojakova APR_RETRIEVE_OPTIONAL_FN(ap_proxy_retry_worker);
d2786879b4733fd4886a5b654f7c6de1d234f638Kristina Sojakova /* can only happen if mod_proxy isn't loaded */
b3bacd257ffcdd346b70ab690f03b28ad5f33fdcKristina Sojakova ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01207)
b3bacd257ffcdd346b70ab690f03b28ad5f33fdcKristina Sojakova "proxy: Entering byrequests for BALANCER (%s)",
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova /* First try to see if we have available candidate */
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova worker = (proxy_worker **)balancer->workers->elts;
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova for (i = 0; i < balancer->workers->nelts; i++, worker++) {
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova if (!checking_standby) { /* first time through */
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova (checking_standby ? !PROXY_WORKER_IS_STANDBY(*worker) : PROXY_WORKER_IS_STANDBY(*worker)) ||
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova /* If the worker is in error state run
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova * retry on that worker. It will be marked as
cur_lbset++;
if (mycandidate) {
return mycandidate;
return APR_SUCCESS;
return APR_SUCCESS;
NULL,
&reset,
&age