[jboss-cvs] JBossAS SVN: r77323 - in trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load: metric and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Aug 21 11:39:31 EDT 2008


Author: pferraro
Date: 2008-08-21 11:39:31 -0400 (Thu, 21 Aug 2008)
New Revision: 77323

Modified:
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/impl/DynamicLoadBalanceFactorProvider.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetric.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetricSource.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetric.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetricSource.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/SingleLoadMetricSource.java
Log:
[JBAS-5661] 2nd draft of LoadManager logic
Fixed time decay function to return true time-decayed average load.
Clarify the roles of weight and capacity in load factor calculation.
Load factor = inverted aggregated load.
Renamed LoadMetric.getBenchmark() to getCapacity().

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/impl/DynamicLoadBalanceFactorProvider.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/impl/DynamicLoadBalanceFactorProvider.java	2008-08-21 15:12:11 UTC (rev 77322)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/impl/DynamicLoadBalanceFactorProvider.java	2008-08-21 15:39:31 UTC (rev 77323)
@@ -23,10 +23,9 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
+import java.util.Map;
 
 import org.apache.log4j.Logger;
 import org.jboss.web.tomcat.service.modcluster.load.LoadBalanceFactorProvider;
@@ -39,41 +38,17 @@
  * 
  * @author Paul Ferraro
  */
-public class DynamicLoadBalanceFactorProvider implements LoadBalanceFactorProvider, LoadMetricSourceRegistration, Runnable
+public class DynamicLoadBalanceFactorProvider implements LoadBalanceFactorProvider, LoadMetricSourceRegistration
 {
    private final Logger log = Logger.getLogger(this.getClass());
-   private final ScheduledExecutorService executor;
    private final Collection<LoadMetricSource> sources = new ArrayList<LoadMetricSource>();
+   private final Map<LoadMetric, List<Double>> loadHistory = new HashMap<LoadMetric, List<Double>>();
    
-   private volatile int loadBalanceFactor = 0;
-   
-   private volatile long recalculationInterval = 60;
    private volatile int decayFactor = 2;
    private volatile int history = 10;
-   
-   private List<Double> loadHistory = new ArrayList<Double>(this.history);
-   
-   public DynamicLoadBalanceFactorProvider(ScheduledExecutorService executor)
-   {
-      this.executor = executor;
-   }
 
-   public DynamicLoadBalanceFactorProvider()
-   {
-      this(Executors.newScheduledThreadPool(1));
-   }
-
    /**
     * @{inheritDoc}
-    * @see org.jboss.web.tomcat.service.modcluster.load.LoadBalanceFactorProvider#getLoadBalanceFactor()
-    */
-   public int getLoadBalanceFactor()
-   {
-      return this.loadBalanceFactor;
-   }
-
-   /**
-    * @{inheritDoc}
     * @see org.jboss.web.tomcat.service.modcluster.load.metric.MetricRegistration#register(org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetricSource)
     */
    public void add(LoadMetricSource source)
@@ -81,19 +56,14 @@
       this.sources.add(source);
    }
    
-   public void start()
+   /**
+    * @{inheritDoc}
+    * @see org.jboss.web.tomcat.service.modcluster.load.LoadBalanceFactorProvider#getLoadBalanceFactor()
+    */
+   public synchronized int getLoadBalanceFactor()
    {
-      this.executor.scheduleWithFixedDelay(this, System.currentTimeMillis(), this.recalculationInterval, TimeUnit.SECONDS);
-   }
-
-   public void stop()
-   {
-      this.executor.shutdown();
-   }
-   
-   public void run()
-   {
-      double load = 0;
+      int totalWeight = 0;
+      double totalWeightedLoad = 0;
       
       for (LoadMetricSource source: this.sources)
       {
@@ -120,8 +90,13 @@
                {
                   try
                   {
-                     // Normalize load with respect to the metric benchmark
-                     load += metric.getWeight() * metric.getLoad() / metric.getBenchmark();
+                     // Normalize load with respect to capacity
+                     List<Double> queue = this.recordLoad(metric, metric.getLoad() / metric.getCapacity());
+
+                     int weight = metric.getWeight();
+                     
+                     totalWeight += weight;
+                     totalWeightedLoad += this.average(queue) * weight;
                   }
                   catch (Exception e)
                   {
@@ -135,51 +110,58 @@
             }
          }
       }
+
+      // Convert load ratio to integer percentage and invert to express as "load factor"
+      return 100 - ((int) (100 * totalWeightedLoad / totalWeight));
+   }
+   
+   private List<Double> recordLoad(LoadMetric metric, double load)
+   {
+      List<Double> queue = this.loadHistory.get(metric);
       
-      if (this.loadHistory.size() >= this.history)
+      if (queue == null)
       {
-         this.loadHistory.remove(0);
+         queue = new ArrayList<Double>(this.history);
+         
+         this.loadHistory.put(metric, queue);
       }
-      
-      double totalLoad = load;
-      
-      // Time-decay old load values
-      for (int i = 0; i < this.loadHistory.size(); ++i)
+      // Remove tail of list if at capacity
+      else if (queue.size() == this.history)
       {
-         double decayedLoad = this.loadHistory.get(i) / this.decayFactor;
-         
-         this.loadHistory.set(i, decayedLoad);
-         
-         totalLoad += decayedLoad;
+         queue.remove(queue.size() - 1);
       }
       
-      // Express aggregated ratios as integer
-      this.loadBalanceFactor = (int) (totalLoad * 100);
+      queue.add(0, new Double(load));
       
-      this.loadHistory.add(new Double(load));
+      return queue;
    }
    
    /**
-    * Get the recalculationInterval.
-    * 
-    * @return the recalculationInterval.
+    * Compute historical average using time decay function
+    * @param queue
+    * @return
     */
-   public long getRecalculationInterval()
+   private double average(List<Double> queue)
    {
-      return this.recalculationInterval;
+      assert !queue.isEmpty();
+      
+      double totalLoad = 0;
+      double totalDecay = 0;
+      double decayFactor = this.decayFactor;
+      
+      // Historical value contribute an exponentially decayed factor
+      for (int i = 0; i < queue.size(); ++i)
+      {
+         double decay = 1 / Math.pow(decayFactor, i);
+         
+         totalDecay += decay;
+         totalLoad += queue.get(i).doubleValue() * decay;
+      }
+      
+      return totalLoad / totalDecay;
    }
 
    /**
-    * Set the interval between load recalculations.
-    * 
-    * @param recalculationInterval The recalculationInterval to set.
-    */
-   public void setRecalculationInterval(long recalculationInterval)
-   {
-      this.recalculationInterval = recalculationInterval;
-   }
-
-   /**
     * Get the decayFactor.
     * 
     * @return the decayFactor.

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetric.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetric.java	2008-08-21 15:12:11 UTC (rev 77322)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetric.java	2008-08-21 15:39:31 UTC (rev 77323)
@@ -30,7 +30,7 @@
 {
    int getWeight();
    
-   double getBenchmark();
+   double getCapacity();
    
    double getLoad() throws Exception;
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetricSource.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetricSource.java	2008-08-21 15:12:11 UTC (rev 77322)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/LoadMetricSource.java	2008-08-21 15:39:31 UTC (rev 77323)
@@ -29,7 +29,7 @@
  */
 public interface LoadMetricSource
 {
-   Collection<? extends LoadMetric> getMetrics();
+   Collection<LoadMetric> getMetrics();
    
    void open();
    

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetric.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetric.java	2008-08-21 15:12:11 UTC (rev 77322)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetric.java	2008-08-21 15:39:31 UTC (rev 77323)
@@ -31,7 +31,7 @@
 public abstract class AbstractLoadMetric implements LoadMetric
 {
    private volatile int weight = 0;
-   private volatile double benchmark = 1;
+   private volatile double capacity = 1;
    
    /**
     * @{inheritDoc}
@@ -49,20 +49,20 @@
 
    /**
     * @{inheritDoc}
-    * @see org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetric#getBenchmark()
+    * @see org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetric#getCapacity()
     */
-   public double getBenchmark()
+   public double getCapacity()
    {
-      return this.benchmark;
+      return this.capacity;
    }
    
-   public void setBenchmark(double benchmark)
+   public void setCapacity(double capacity)
    {
-      if (benchmark <= 0)
+      if (capacity <= 0)
       {
-         throw new IllegalArgumentException("Benchmark be greater than zero.");
+         throw new IllegalArgumentException("Capacity be greater than zero.");
       }
       
-      this.benchmark = benchmark;
+      this.capacity = capacity;
    }
 }
\ No newline at end of file

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetricSource.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetricSource.java	2008-08-21 15:12:11 UTC (rev 77322)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/AbstractLoadMetricSource.java	2008-08-21 15:39:31 UTC (rev 77323)
@@ -51,7 +51,7 @@
     * @{inheritDoc}
     * @see org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetricSource#getMetrics()
     */
-   public Collection<? extends LoadMetric> getMetrics()
+   public Collection<LoadMetric> getMetrics()
    {
       return this.metrics;
    }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/SingleLoadMetricSource.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/SingleLoadMetricSource.java	2008-08-21 15:12:11 UTC (rev 77322)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/metric/impl/SingleLoadMetricSource.java	2008-08-21 15:39:31 UTC (rev 77323)
@@ -63,8 +63,9 @@
     * @{inheritDoc}
     * @see org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetricSource#getMetrics()
     */
-   public Collection<? extends LoadMetric> getMetrics()
+   public Collection<LoadMetric> getMetrics()
    {
-      return Collections.singleton(this);
+      // Silly that we need to cast to prevent a compiler error, no?
+      return Collections.singleton((LoadMetric) this);
    }
 }




More information about the jboss-cvs-commits mailing list