myserver-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myserver-commit] [3080] Simple ip-hashing based load balancing for SCGI


From: Giuseppe Scrivano
Subject: [myserver-commit] [3080] Simple ip-hashing based load balancing for SCGI/FastCGI servers, a set of equivalent servers is kept referred by the same name.
Date: Mon, 04 May 2009 20:36:59 +0000

Revision: 3080
          http://svn.sv.gnu.org/viewvc/?view=rev&root=myserver&revision=3080
Author:   gscrivano
Date:     2009-05-04 20:36:59 +0000 (Mon, 04 May 2009)
Log Message:
-----------
Simple ip-hashing based load balancing for SCGI/FastCGI servers, a set of 
equivalent servers is kept referred by the same name.

Modified Paths:
--------------
    trunk/myserver/include/base/process/process_server_manager.h
    trunk/myserver/src/base/process/process_server_manager.cpp
    trunk/myserver/src/http_handler/fastcgi/fastcgi.cpp
    trunk/myserver/src/http_handler/scgi/scgi.cpp

Modified: trunk/myserver/include/base/process/process_server_manager.h
===================================================================
--- trunk/myserver/include/base/process/process_server_manager.h        
2009-05-04 18:34:16 UTC (rev 3079)
+++ trunk/myserver/include/base/process/process_server_manager.h        
2009-05-04 20:36:59 UTC (rev 3080)
@@ -29,6 +29,7 @@
 #include <include/base/hash_map/hash_map.h>
 #include <string>
 
+#include <vector>
 using namespace std;
 
 class ProcessServerManager
@@ -66,7 +67,7 @@
        struct ServerDomain
        {
                string domainName;
-               HashMap<string, Server*> servers;
+               HashMap<string, vector<Server*>* > servers;
                void (*clear)(Server*);
                ServerDomain()
                {
@@ -77,13 +78,12 @@
        ServerDomain* createDomain(const char* name);
        ServerDomain* getDomain(const char* name);
        void clear();
-       Server* getServer(const char* domain, const char* name);
+       Server* getServer(const char* domain, const char* name, int seed = 0);
        ProcessServerManager();
        ~ProcessServerManager();
        int connect(Socket* sock, Server* server);
        void setMaxServers(int max){maxServers = max;}
        int getMaxServers(){return maxServers;}
-       void removeServer(const char* domain, const char* name);
        void removeDomain(const char* domain);
        int domainServers(const char* domain);
        void load();

Modified: trunk/myserver/src/base/process/process_server_manager.cpp
===================================================================
--- trunk/myserver/src/base/process/process_server_manager.cpp  2009-05-04 
18:34:16 UTC (rev 3079)
+++ trunk/myserver/src/base/process/process_server_manager.cpp  2009-05-04 
20:36:59 UTC (rev 3080)
@@ -152,7 +152,7 @@
  *\param name The domain name.
  */
 ProcessServerManager::ServerDomain* 
-ProcessServerManager::createDomain(const char* name)
+ProcessServerManager::createDomain (const char* name)
 {
   ServerDomain* ret;
 
@@ -182,23 +182,31 @@
 
   it = domains.begin();
 
-  for(;it != domains.end(); it++)
-  {
-    ServerDomain *sd = *it;
-    HashMap<string, Server*>::Iterator server = sd->servers.begin();
-
-    for(;server != sd->servers.end(); server++)
+  for (;it != domains.end(); it++)
     {
-      if((*it)->clear)
-      {
-        (*it)->clear(*server);
-      }
-      if((*server)->isLocal)
-        nServers--;
-      (*server)->terminate();
-      delete (*server);
-    }
-    delete (*it);
+      ServerDomain *sd = *it;
+      HashMap<string, vector<Server*>*>::Iterator server = sd->servers.begin();
+
+      for (; server != sd->servers.end (); server++)
+        {
+          for (vector<Server*>::iterator it = (*server)->begin ();
+               it != (*server)->end ();
+               it++)
+            {
+              Server *s = *it;
+
+              if(s->isLocal)
+                nServers--;
+
+              if (sd->clear)
+                sd->clear(s);
+
+              s->terminate();
+              delete s;
+            }
+          delete (*server);
+        }
+      delete (*it);
   }
   domains.clear();
   mutex.unlock();
@@ -208,16 +216,22 @@
  *Get a server is running by its domain and name.
  *\param domain The domain name.
  *\param name The server name name.
+ *\param seed Random seed to use for choosing a server.
  */
 ProcessServerManager::Server* 
-ProcessServerManager::getServer(const char* domain, const char* name)
+ProcessServerManager::getServer(const char* domain, const char* name, int seed)
 {
   ServerDomain* sd;
   Server* s;
+
   mutex.lock();
   sd = domains.get(domain);
+
   if(sd)
-    s = sd->servers.get(name);
+    {
+      vector<Server*> *slist = sd->servers.get (name);
+      s = slist->at (seed % slist->size ());
+    }
   else
     s = 0;
   
@@ -251,19 +265,21 @@
 void ProcessServerManager::addServer(ProcessServerManager::Server* server, 
                                      const char* domain, const char* name)
 {
-  ServerDomain* sd = createDomain(domain);
-  Server* old;
-  string str(name);
+  ServerDomain *sd = createDomain (domain);
+  Server *old;
+  string strName (name);
 
   mutex.lock();
+  vector<Server*>* slist = sd->servers.get (strName);
 
-  old = sd->servers.put(str, server);
+  if (slist == NULL)
+    {
+      slist = new vector<Server*> ();
+      sd->servers.put (strName, slist);
+    }
 
-  if(old)
-  {
-    old->terminate();
-    delete old;
-  }
+  slist->push_back (server);
+
   mutex.unlock();
 }
 
@@ -275,16 +291,16 @@
  *\param port The port number to use for the connection.
  */
 ProcessServerManager::Server* 
-ProcessServerManager::addRemoteServer(const char* domain, const char* name, 
-                                      const char* host, u_short port)
+ProcessServerManager::addRemoteServer (const char* domain, const char* name,
+                                       const char* host, u_short port)
 {
   Server* server = new Server;
-  server->path.assign(name);
-  server->host.assign(host);
+  server->path.assign (name);
+  server->host.assign (host);
   server->port = port;
   server->isLocal = false;
 
-  addServer(server, domain, name);
+  addServer (server, domain, name);
   return server;
 }
 
@@ -292,62 +308,40 @@
  *Remove a domain by its name.
  *\param domain The domain name.
  */
-void ProcessServerManager::removeDomain(const char* domain)
+void ProcessServerManager::removeDomain (const char* domain)
 {
   ServerDomain *sd;
   HashMap<string, Server*>::Iterator server;
 
   mutex.lock();
 
-  sd = getDomain(domain);
-  if(sd)
-  {
-    server = sd->servers.begin();
-    
-    for(;server != sd->servers.end(); server++)
+  sd = getDomain (domain);
+
+  if (sd)
     {
-      if(sd->clear)
-      {
-        sd->clear(*server);
-      }
-      if((*server)->isLocal)
-        nServers--;
-      (*server)->terminate();
-      delete (*server);
-    }
-    delete sd;
-  }
+      HashMap<string, vector<Server*>*>::Iterator server = sd->servers.begin 
();
 
-  mutex.unlock();
-}
+      for (; server != sd->servers.end (); server++)
+        {
+          for (vector<Server*>::iterator it = (*server)->begin ();
+               it != (*server)->end ();
+               it++)
+            {
+              Server *s = *it;
 
-/*!
- *Remove a server by its domain and name.
- *\param domain The server domain.
- *\param name The server name.
- */
-void ProcessServerManager::removeServer(const char* domain, const char* name)
-{
-  ServerDomain* sd;
-  Server* server;
-  mutex.lock();
-  sd = domains.get(domain);
-  if(sd)
-    server = sd->servers.remove(name);
-  else
-    server = 0;
-  
-  if(server)
-  {
-    if(server->isLocal)
-    {
-      if(sd->clear)
-        sd->clear(server);
-      server->terminate();
-      nServers--;
+              if(s->isLocal)
+                nServers--;
+
+              if (sd->clear)
+                sd->clear(s);
+
+              s->terminate ();
+              delete s;
+            }
+          delete (*server);
+        }
+      delete sd;
     }
-    delete server;
-  }
 
   mutex.unlock();
 }

Modified: trunk/myserver/src/http_handler/fastcgi/fastcgi.cpp
===================================================================
--- trunk/myserver/src/http_handler/fastcgi/fastcgi.cpp 2009-05-04 18:34:16 UTC 
(rev 3079)
+++ trunk/myserver/src/http_handler/fastcgi/fastcgi.cpp 2009-05-04 20:36:59 UTC 
(rev 3080)
@@ -1,6 +1,6 @@
 /*
 MyServer
-Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software 
Foundation, Inc.
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
@@ -512,8 +512,17 @@
 FastCgiServer* FastCgi::runFcgiServer(FcgiContext* context, 
                                       const char* path)
 {
-  FastCgiServer* server =  processServerManager->getServer(SERVERS_DOMAIN, 
-                                                          path);
+  /* This method needs a better home (and maybe better code).
+   * Compute a simple hash from the IP address.  */
+  const char *ip = context->td->connection->getIpAddr();
+  int seed = 13;
+  for (const char *c = ip; c; c++)
+    seed = *c * 21 + seed;
+
+  FastCgiServer* server = processServerManager->getServer(SERVERS_DOMAIN,
+                                                          path,
+                                                          seed);
+
   if(server)
     return server;
 

Modified: trunk/myserver/src/http_handler/scgi/scgi.cpp
===================================================================
--- trunk/myserver/src/http_handler/scgi/scgi.cpp       2009-05-04 18:34:16 UTC 
(rev 3079)
+++ trunk/myserver/src/http_handler/scgi/scgi.cpp       2009-05-04 20:36:59 UTC 
(rev 3080)
@@ -1,6 +1,6 @@
 /*
 MyServer
-Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software 
Foundation, Inc.
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
@@ -538,8 +538,16 @@
 ScgiServer* Scgi::runScgiServer(ScgiContext* context, 
                                 const char* path)
 {
+  /* This method needs a better home (and maybe better code).
+   * Compute a simple hash from the IP address.  */
+  const char *ip = context->td->connection->getIpAddr();
+  int seed = 13;
+  for (const char *c = ip; c; c++)
+    seed = *c * 21 + seed;
+
   ScgiServer* server =  processServerManager->getServer(SERVERS_DOMAIN, 
-                                                        path);
+                                                        path,
+                                                        seed);
   if(server)
     return server;
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]