Use "currently_outstanding" metric for load-balance. i.e. we choose
authoraland <aland>
Mon, 14 May 2007 09:42:51 +0000 (09:42 +0000)
committeraland <aland>
Mon, 14 May 2007 09:42:51 +0000 (09:42 +0000)
the home server with the lowest "currently_outstanding" number.
If there are multiple home servers with the same number, randomly
choose among them.

This means that when a home server is dead and doesn't respond,
the requests will immediately be load-balanced to any live servers

src/main/realms.c

index 42edf62..54e7cee 100644 (file)
@@ -1030,6 +1030,7 @@ home_server *home_server_ldb(const char *realmname,
 {
        int             start;
        int             count;
+       home_server     *found = NULL;
 
        start = 0;
 
@@ -1040,14 +1041,6 @@ home_server *home_server_ldb(const char *realmname,
                uint32_t hash;
 
                /*
-                *      Load balancing.  Pick one at random.
-                */
-       case HOME_POOL_LOAD_BALANCE:
-               hash = lrad_rand();
-               start = hash % pool->num_home_servers;
-               break;
-
-               /*
                 *      For load-balancing by client IP address, we
                 *      pick a home server by hashing the client IP.
                 *
@@ -1072,6 +1065,9 @@ home_server *home_server_ldb(const char *realmname,
                start = hash % pool->num_home_servers;
                break;
 
+       case HOME_POOL_LOAD_BALANCE:
+               found = pool->servers[0];
+
        default:
                start = 0;
                break;
@@ -1098,9 +1094,47 @@ home_server *home_server_ldb(const char *realmname,
                        continue;
                }
 
-               return home;
+               if (pool->type != HOME_POOL_LOAD_BALANCE) {
+                       return home;
+               }
+
+               DEBUG3("PROXY %s %d\t%s %d",
+                      found->name, found->currently_outstanding,
+                      home->name, home->currently_outstanding);
+
+               /*
+                *      Prefer this server if it's less busy than the
+                *      one we previously found.
+                */
+               if (home->currently_outstanding < found->currently_outstanding) {
+                       DEBUG3("Choosing %s: It's less busy than %s",
+                              home->name, found->name);
+                       found = home;
+                       continue;
+               }
+
+               /*
+                *      Ignore servers which are busier than the one
+                *      we found.
+                */
+               if (home->currently_outstanding > found->currently_outstanding) {
+                       DEBUG3("Skipping %s: It's busier than %s",
+                              home->name, found->name);
+                       continue;
+               }
+
+               /*
+                *      From the list of servers which have the same
+                *      load, choose one at random.
+                */
+               if (((count + 1) * (lrad_rand() & 0xffff)) < (uint32_t) 0x10000) {
+                       found = home;
+               }
+
        } /* loop over the home servers */
 
+       if (found) return found;
+
        /*
         *      No live match found, and no fallback to the "DEFAULT"
         *      realm.  We fix this by blindly marking all servers as