]> granicus.if.org Git - apache/commitdiff
Restruct of lbmethod find-best algo's, bypassing hook mechanism.
authorJim Jagielski <jim@apache.org>
Wed, 7 Sep 2005 12:04:15 +0000 (12:04 +0000)
committerJim Jagielski <jim@apache.org>
Wed, 7 Sep 2005 12:04:15 +0000 (12:04 +0000)
Looking into provider method, but until then... Prevent core dump
when balancer not in vhosts

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@279305 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_balancer.c
modules/proxy/proxy_util.c

index 1f3de0c117a9f1e8ca58bf9f4b82b93cf459dc89..9cac88778fd63593567854834f5811555e4d74cb 100644 (file)
@@ -822,7 +822,7 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s)
     ps->badopt_set = 0;
     ps->pool = p;
     
-    proxy_run_load_lbmethods(ps);
+    ap_proxy_add_lbmethods(ps);
     
     return ps;
 }
@@ -1925,7 +1925,6 @@ APR_HOOK_STRUCT(
     APR_HOOK_LINK(canon_handler)
     APR_HOOK_LINK(pre_request)
     APR_HOOK_LINK(post_request)
-    APR_HOOK_LINK(load_lbmethods)
     APR_HOOK_LINK(request_status)
 )
 
@@ -1951,10 +1950,6 @@ APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, post_request,
                                        request_rec *r,
                                        proxy_server_conf *conf),(worker,
                                        balancer,r,conf),DECLINED)
-APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(proxy, PROXY, int, load_lbmethods,
-                                    (proxy_server_conf *conf), 
-                                    (conf),
-                                    OK, DECLINED)
 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups,
                                     (request_rec *r), (r),
                                     OK, DECLINED)
index fd223ad1a266189218f26a8e497cc71c437d7af6..5cbaed148c4a0ab389d6c4b81794665fd1e4016f 100644 (file)
@@ -379,14 +379,6 @@ APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r,
 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r)) 
 
-/*
- * Useful hook run within the create per-server phase which
- * adds the required lbmethod structs, so they exist at
- * configure time
- */
-APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, load_lbmethods,
-                                     (proxy_server_conf *conf))
-
 /**
  * pre request hook.
  * It will return the most suitable worker at the moment
@@ -678,6 +670,14 @@ PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
                                               proxy_conn_rec *conn,
                                               conn_rec *c, server_rec *s);
 
+/**
+ * Load in available lb methods
+ * @param conf    server conf
+ * @return        OK or HTTP_XXX error
+ */                                         
+
+PROXY_DECLARE(int) ap_proxy_add_lbmethods(proxy_server_conf *conf);
+
 /* Scoreboard */
 #if MODULE_MAGIC_NUMBER_MAJOR > 20020903
 #define PROXY_HAS_SCOREBOARD 1
index 0d9921e96c696b9228dae8f21ade2b4609f5b975..7bb3d1252f090482dab7b3da04e0b139538a47be 100644 (file)
@@ -218,156 +218,6 @@ static proxy_worker *find_session_route(proxy_balancer *balancer,
         return NULL;
 }
 
-/*
- * The idea behind the find_best_byrequests scheduler is the following:
- *
- * lbfactor is "how much we expect this worker to work", or "the worker's
- * normalized work quota".
- *
- * lbstatus is "how urgent this worker has to work to fulfill its quota
- * of work".
- *
- * We distribute each worker's work quota to the worker, and then look
- * which of them needs to work most urgently (biggest lbstatus).  This
- * worker is then selected for work, and its lbstatus reduced by the
- * total work quota we distributed to all workers.  Thus the sum of all
- * lbstatus does not change.(*)
- *
- * If some workers are disabled, the others will
- * still be scheduled correctly.
- *
- * If a balancer is configured as follows:
- *
- * worker     a    b    c    d
- * lbfactor  25   25   25   25
- *
- * And b gets disabled, the following schedule is produced:
- *
- *    a c d a c d a c d ...
- *
- * Note that the above lbfactor setting is the *exact* same as:
- *
- * worker     a    b    c    d
- * lbfactor   1    1    1    1
- *
- * Asymmetric configurations work as one would expect. For
- * example:
- *
- * worker     a    b    c    d
- * lbfactor   1    1    1    2
- *
- * would have a, b and c all handling about the same
- * amount of load with d handling twice what a or b
- * or c handles individually. So we could see:
- *
- *   b a d c d a c d b d ...
- *
- */
-static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
-                                request_rec *r)
-{
-    int i;
-    int total_factor = 0;
-    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
-    proxy_worker *mycandidate = NULL;
-
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                 "proxy: Entering byrequests for BALANCER (%s)",
-                 balancer->name);
-
-    /* First try to see if we have available candidate */
-    for (i = 0; i < balancer->workers->nelts; i++) {
-        /* If the worker is in error state run
-         * retry on that worker. It will be marked as
-         * operational if the retry timeout is elapsed.
-         * The worker might still be unusable, but we try
-         * anyway.
-         */
-        if (!PROXY_WORKER_IS_USABLE(worker))
-            ap_proxy_retry_worker("BALANCER", worker, r->server);
-        /* 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;
-        }
-        worker++;
-    }
-
-    if (mycandidate) {
-        mycandidate->s->lbstatus -= total_factor;
-        mycandidate->s->elected++;
-    }
-
-    return mycandidate;
-}
-
-/*
- * The idea behind the find_best_bytraffic scheduler is the following:
- *
- * We know the amount of traffic (bytes in and out) handled by each
- * worker. We normalize that traffic by each workers' weight. So assuming
- * a setup as below:
- *
- * worker     a    b    c
- * lbfactor   1    1    3
- *
- * the scheduler will allow worker c to handle 3 times the
- * traffic of a and b. If each request/response results in the
- * same amount of traffic, then c would be accessed 3 times as
- * often as a or b. If, for example, a handled a request that
- * resulted in a large i/o bytecount, then b and c would be
- * chosen more often, to even things out.
- */
-static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
-                                         request_rec *r)
-{
-    int i;
-    apr_off_t mytraffic = 0;
-    apr_off_t curmin = 0;
-    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
-    proxy_worker *mycandidate = NULL;
-    
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                 "proxy: Entering bytraffic for BALANCER (%s)",
-                 balancer->name);
-
-    /* First try to see if we have available candidate */
-    for (i = 0; i < balancer->workers->nelts; i++) {
-        /* If the worker is in error state run
-         * retry on that worker. It will be marked as
-         * operational if the retry timeout is elapsed.
-         * The worker might still be unusable, but we try
-         * anyway.
-         */
-        if (!PROXY_WORKER_IS_USABLE(worker))
-            ap_proxy_retry_worker("BALANCER", worker, r->server);
-        /* Take into calculation only the workers that are
-         * 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;
-            }
-        }
-        worker++;
-    }
-    
-    if (mycandidate) {
-        mycandidate->s->elected++;
-    }
-
-    return mycandidate;
-}
-
 static proxy_worker *find_best_worker(proxy_balancer *balancer,
                                       request_rec *r)
 {
@@ -888,30 +738,6 @@ static void child_init(apr_pool_t *p, server_rec *s)
 
 }
 
-/*
- * How to add additional lbmethods:
- *   1. Create func which determines "best" candidate worker
- *      (eg: find_best_bytraffic, above)
- *   2. Create proxy_balancer_method struct which
- *      defines the method and add it to
- *      available server methods using
- *      the proxy_hook_load_lbmethods hook
- *      (eg: add_lbmethods below).
- */
-static int add_lbmethods(proxy_server_conf *conf)
-{
-    proxy_balancer_method *new;
-
-    new  = apr_array_push(conf->lbmethods);
-    new->name = "byrequests";
-    new->finder = find_best_byrequests;
-    new  = apr_array_push(conf->lbmethods);
-    new->name = "bytraffic";
-    new->finder = find_best_bytraffic;
-
-    return OK;
-}
-
 static void ap_proxy_balancer_register_hook(apr_pool_t *p)
 {
     /* Only the mpm_winnt has child init hook handler.
@@ -925,7 +751,6 @@ static void ap_proxy_balancer_register_hook(apr_pool_t *p)
     proxy_hook_pre_request(proxy_balancer_pre_request, NULL, NULL, APR_HOOK_FIRST);    
     proxy_hook_post_request(proxy_balancer_post_request, NULL, NULL, APR_HOOK_FIRST);    
     proxy_hook_canon_handler(proxy_balancer_canon, NULL, NULL, APR_HOOK_FIRST);
-    proxy_hook_load_lbmethods(add_lbmethods, NULL, NULL, APR_HOOK_FIRST);
 }
 
 module AP_MODULE_DECLARE_DATA proxy_balancer_module = {
index b12a955edb6c19ab88b4554cbc5ede98b14abfcc..15d9c610423e954ff0bee94b5756fc79a309095b 100644 (file)
@@ -2069,3 +2069,176 @@ int ap_proxy_lb_workers(void)
     lb_workers_limit = proxy_lb_workers + PROXY_DYNAMIC_BALANCER_LIMIT;
     return lb_workers_limit;
 }
+
+/*
+ * The idea behind the find_best_byrequests scheduler is the following:
+ *
+ * lbfactor is "how much we expect this worker to work", or "the worker's
+ * normalized work quota".
+ *
+ * lbstatus is "how urgent this worker has to work to fulfill its quota
+ * of work".
+ *
+ * We distribute each worker's work quota to the worker, and then look
+ * which of them needs to work most urgently (biggest lbstatus).  This
+ * worker is then selected for work, and its lbstatus reduced by the
+ * total work quota we distributed to all workers.  Thus the sum of all
+ * lbstatus does not change.(*)
+ *
+ * If some workers are disabled, the others will
+ * still be scheduled correctly.
+ *
+ * If a balancer is configured as follows:
+ *
+ * worker     a    b    c    d
+ * lbfactor  25   25   25   25
+ *
+ * And b gets disabled, the following schedule is produced:
+ *
+ *    a c d a c d a c d ...
+ *
+ * Note that the above lbfactor setting is the *exact* same as:
+ *
+ * worker     a    b    c    d
+ * lbfactor   1    1    1    1
+ *
+ * Asymmetric configurations work as one would expect. For
+ * example:
+ *
+ * worker     a    b    c    d
+ * lbfactor   1    1    1    2
+ *
+ * would have a, b and c all handling about the same
+ * amount of load with d handling twice what a or b
+ * or c handles individually. So we could see:
+ *
+ *   b a d c d a c d b d ...
+ *
+ */
+static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
+                                request_rec *r)
+{
+    int i;
+    int total_factor = 0;
+    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
+    proxy_worker *mycandidate = NULL;
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                 "proxy: Entering byrequests for BALANCER (%s)",
+                 balancer->name);
+
+    /* First try to see if we have available candidate */
+    for (i = 0; i < balancer->workers->nelts; i++) {
+        /* If the worker is in error state run
+         * retry on that worker. It will be marked as
+         * operational if the retry timeout is elapsed.
+         * The worker might still be unusable, but we try
+         * anyway.
+         */
+        if (!PROXY_WORKER_IS_USABLE(worker))
+            ap_proxy_retry_worker("BALANCER", worker, r->server);
+        /* 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;
+        }
+        worker++;
+    }
+
+    if (mycandidate) {
+        mycandidate->s->lbstatus -= total_factor;
+        mycandidate->s->elected++;
+    }
+
+    return mycandidate;
+}
+
+/*
+ * The idea behind the find_best_bytraffic scheduler is the following:
+ *
+ * We know the amount of traffic (bytes in and out) handled by each
+ * worker. We normalize that traffic by each workers' weight. So assuming
+ * a setup as below:
+ *
+ * worker     a    b    c
+ * lbfactor   1    1    3
+ *
+ * the scheduler will allow worker c to handle 3 times the
+ * traffic of a and b. If each request/response results in the
+ * same amount of traffic, then c would be accessed 3 times as
+ * often as a or b. If, for example, a handled a request that
+ * resulted in a large i/o bytecount, then b and c would be
+ * chosen more often, to even things out.
+ */
+static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
+                                         request_rec *r)
+{
+    int i;
+    apr_off_t mytraffic = 0;
+    apr_off_t curmin = 0;
+    proxy_worker *worker = (proxy_worker *)balancer->workers->elts;
+    proxy_worker *mycandidate = NULL;
+    
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                 "proxy: Entering bytraffic for BALANCER (%s)",
+                 balancer->name);
+
+    /* First try to see if we have available candidate */
+    for (i = 0; i < balancer->workers->nelts; i++) {
+        /* If the worker is in error state run
+         * retry on that worker. It will be marked as
+         * operational if the retry timeout is elapsed.
+         * The worker might still be unusable, but we try
+         * anyway.
+         */
+        if (!PROXY_WORKER_IS_USABLE(worker))
+            ap_proxy_retry_worker("BALANCER", worker, r->server);
+        /* Take into calculation only the workers that are
+         * 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;
+            }
+        }
+        worker++;
+    }
+    
+    if (mycandidate) {
+        mycandidate->s->elected++;
+    }
+
+    return mycandidate;
+}
+
+/*
+ * How to add additional lbmethods:
+ *   1. Create func which determines "best" candidate worker
+ *      (eg: find_best_bytraffic, above)
+ *   2. Create proxy_balancer_method struct which
+ *      defines the method and add it to
+ *      available server methods using
+ *      ap_proxy_add_lbmethods.
+ */
+PROXY_DECLARE(int) ap_proxy_add_lbmethods(proxy_server_conf *conf)
+{
+    proxy_balancer_method *new;
+
+    new  = apr_array_push(conf->lbmethods);
+    new->name = "byrequests";
+    new->finder = find_best_byrequests;
+    new  = apr_array_push(conf->lbmethods);
+    new->name = "bytraffic";
+    new->finder = find_best_bytraffic;
+
+    return OK;
+}