[jboss-cvs] JBossAS SVN: r77159 - trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/impl.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Aug 18 10:35:22 EDT 2008
Author: pferraro
Date: 2008-08-18 10:35:22 -0400 (Mon, 18 Aug 2008)
New Revision: 77159
Added:
trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/impl/DynamicLoadBalanceFactorProvider.java
Log:
[JBAS-5662] Define API and SPI for the LoadManager.
Initial draft. Uses periodic load calculation with time-decay function.
Added: 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 (rev 0)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/modcluster/load/impl/DynamicLoadBalanceFactorProvider.java 2008-08-18 14:35:22 UTC (rev 77159)
@@ -0,0 +1,231 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.modcluster.load.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.Logger;
+import org.jboss.web.tomcat.service.modcluster.load.LoadBalanceFactorProvider;
+import org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetric;
+import org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetricSource;
+import org.jboss.web.tomcat.service.modcluster.load.metric.LoadMetricSourceRegistration;
+
+/**
+ * {@link LoadBalanceFactorProvider} implementation that periodically aggregates load from a set of {@link LoadMetricSource}s.
+ *
+ * @author Paul Ferraro
+ */
+public class DynamicLoadBalanceFactorProvider implements LoadBalanceFactorProvider, LoadMetricSourceRegistration, Runnable
+{
+ private final Logger log = Logger.getLogger(this.getClass());
+ private final ScheduledExecutorService executor;
+ private final Collection<LoadMetricSource> sources = new ArrayList<LoadMetricSource>();
+
+ 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)
+ {
+ this.sources.add(source);
+ }
+
+ public void start()
+ {
+ this.executor.scheduleWithFixedDelay(this, System.currentTimeMillis(), this.recalculationInterval, TimeUnit.SECONDS);
+ }
+
+ public void stop()
+ {
+ this.executor.shutdown();
+ }
+
+ public void run()
+ {
+ double load = 0;
+
+ for (LoadMetricSource source: this.sources)
+ {
+ Collection<? extends LoadMetric> metrics = source.getMetrics();
+
+ List<LoadMetric> metricList = new ArrayList<LoadMetric>(metrics.size());
+
+ // Prune 0 weights since they will not contribute anything
+ for (LoadMetric metric: metrics)
+ {
+ if (metric.getWeight() != 0)
+ {
+ metricList.add(metric);
+ }
+ }
+
+ if (!metricList.isEmpty())
+ {
+ source.open();
+
+ try
+ {
+ for (LoadMetric metric: metricList)
+ {
+ try
+ {
+ // Normalize load with respect to the metric benchmark
+ load += metric.getWeight() * metric.getLoad() / metric.getBenchmark();
+ }
+ catch (Exception e)
+ {
+ this.log.error(e.getMessage(), e);
+ }
+ }
+ }
+ finally
+ {
+ source.close();
+ }
+ }
+ }
+
+ if (this.loadHistory.size() >= this.history)
+ {
+ this.loadHistory.remove(0);
+ }
+
+ double totalLoad = load;
+
+ // Time-decay old load values
+ for (int i = 0; i < this.loadHistory.size(); ++i)
+ {
+ double decayedLoad = this.loadHistory.get(i) / this.decayFactor;
+
+ this.loadHistory.set(i, decayedLoad);
+
+ totalLoad += decayedLoad;
+ }
+
+ // Express aggregated ratios as integer
+ this.loadBalanceFactor = (int) (totalLoad * 100);
+
+ this.loadHistory.add(new Double(load));
+ }
+
+ /**
+ * Get the recalculationInterval.
+ *
+ * @return the recalculationInterval.
+ */
+ public long getRecalculationInterval()
+ {
+ return this.recalculationInterval;
+ }
+
+ /**
+ * 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.
+ */
+ public int getDecayFactor()
+ {
+ return this.decayFactor;
+ }
+
+ /**
+ * Set the exponential decay factor applied to historic load values.
+ *
+ * @param decayFactor The decayFactor to set.
+ */
+ public void setDecayFactor(int decayFactor)
+ {
+ if (decayFactor <= 0)
+ {
+ throw new IllegalArgumentException("Decay factor must be greater than 0.");
+ }
+
+ this.decayFactor = decayFactor;
+ }
+
+ /**
+ * Get the history.
+ *
+ * @return the history.
+ */
+ public int getHistory()
+ {
+ return this.history;
+ }
+
+ /**
+ * Set the number of historic load values to consider when calculating the current load factor.
+ *
+ * @param history The history to set.
+ */
+ public void setHistory(int history)
+ {
+ if (history <= 0)
+ {
+ throw new IllegalArgumentException("History must be greater than 0.");
+ }
+
+ this.history = history;
+ }
+}
More information about the jboss-cvs-commits
mailing list