Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;

/**
/**
* Rule that use the average/percentile response times
* to assign dynamic "weights" per Server which is then used in
* the "Weighted Round Robin" fashion.
* to assign dynamic "weights" per Server which is then used in
* the "Weighted Round Robin" fashion.
* <p>
* The basic idea for weighted round robin has been obtained from JCS
* The implementation for choosing the endpoint from the list of endpoints
* is as follows:Let's assume 4 endpoints:A(wt=10), B(wt=30), C(wt=40),
* D(wt=20).
* is as follows:Let's assume 4 endpoints:A(wt=10), B(wt=30), C(wt=40),
* D(wt=20).
* <p>
* Using the Random API, generate a random number between 1 and10+30+40+20.
* Let's assume that the above list is randomized. Based on the weights, we
Expand All @@ -51,7 +51,7 @@
* <br>
* 41----80 (A's weight + B's weight + C's weight)
* <br>
* 81----100(A's weight + B's weight + C's weight + C's weight)
* 81----100(A's weight + B's weight + C's weight + D's weight)
* <p>
* Here's the psuedo code for deciding where to send the request:
* <p>
Expand All @@ -64,7 +64,7 @@
* else if (random_number between 81 &amp; 100) {send request to D;}
* <p>
* When there is not enough statistics gathered for the servers, this rule
* will fall back to use {@link RoundRobinRule}.
* will fall back to use {@link RoundRobinRule}.
* @author stonse
*/
public class WeightedResponseTimeRule extends RoundRobinRule {
Expand All @@ -74,7 +74,7 @@ public class WeightedResponseTimeRule extends RoundRobinRule {
public String key() {
return "ServerWeightTaskTimerInterval";
}

@Override
public String toString() {
return key();
Expand All @@ -85,17 +85,17 @@ public Class<Integer> type() {
return Integer.class;
}
};

public static final int DEFAULT_TIMER_INTERVAL = 30 * 1000;

private int serverWeightTaskTimerInterval = DEFAULT_TIMER_INTERVAL;

private static final Logger logger = LoggerFactory.getLogger(WeightedResponseTimeRule.class);

// holds the accumulated weight from index 0 to current index
// for example, element at index 2 holds the sum of weight of servers from 0 to 2
private volatile List<Double> accumulatedWeights = new ArrayList<Double>();


private final Random random = new Random();

Expand All @@ -112,7 +112,7 @@ public WeightedResponseTimeRule() {
public WeightedResponseTimeRule(ILoadBalancer lb) {
super(lb);
}

@Override
public void setLoadBalancer(ILoadBalancer lb) {
super.setLoadBalancer(lb);
Expand All @@ -122,7 +122,7 @@ public void setLoadBalancer(ILoadBalancer lb) {
initialize(lb);
}

void initialize(ILoadBalancer lb) {
void initialize(ILoadBalancer lb) {
if (serverWeightTimer != null) {
serverWeightTimer.cancel();
}
Expand Down Expand Up @@ -180,7 +180,7 @@ public Server choose(ILoadBalancer lb, Object key) {
int serverIndex = 0;

// last one in the list is the sum of all weights
double maxTotalWeight = currentWeights.size() == 0 ? 0 : currentWeights.get(currentWeights.size() - 1);
double maxTotalWeight = currentWeights.size() == 0 ? 0 : currentWeights.get(currentWeights.size() - 1);
// No server has been hit yet and total weight is not initialized
// fallback to use round robin
if (maxTotalWeight < 0.001d || serverCount != currentWeights.size()) {
Expand Down Expand Up @@ -239,11 +239,11 @@ public void maintainWeights() {
if (lb == null) {
return;
}

if (!serverWeightAssignmentInProgress.compareAndSet(false, true)) {
return;
return;
}

try {
logger.info("Weight adjusting job started");
AbstractLoadBalancer nlb = (AbstractLoadBalancer) lb;
Expand All @@ -262,14 +262,14 @@ public void maintainWeights() {
// weight for each server is (sum of responseTime of all servers - responseTime)
// so that the longer the response time, the less the weight and the less likely to be chosen
Double weightSoFar = 0.0;

// create new list and hot swap the reference
List<Double> finalWeights = new ArrayList<Double>();
for (Server server : nlb.getAllServers()) {
ServerStats ss = stats.getSingleServerStat(server);
double weight = totalResponseTime - ss.getResponseTimeAvg();
weightSoFar += weight;
finalWeights.add(weightSoFar);
finalWeights.add(weightSoFar);
}
setWeights(finalWeights);
} catch (Exception e) {
Expand Down