public LoadBalancerPolicy(String param, Map<String, String> params) { super(params); cluster = params.get("cluster"); session = params.get("session"); if (cluster == null) { error = "Required parameter pattern not set"; return; } if (session == null) { error = "Required parameter session not set"; return; } metrics = new LoadBalancer.Metrics(param); metrics.setXmlTagName("loadbalancer"); pattern = cluster + "/*/" + session; loadBalancer = new LoadBalancer(cluster, session, metrics); }
/** * Returns the node metrics at a given index. * If there is no entry at the given index it is created by this call. */ private NodeMetrics getNodeMetrics(Mirror.Entry entry) { int index = getIndex(entry.getName()); // expand node array as needed while (nodeWeights.size() < (index + 1)) nodeWeights.add(null); NodeMetrics nodeMetrics = nodeWeights.get(index); if (nodeMetrics == null) { // initialize statistics for this node nodeMetrics = new NodeMetrics("node_" + index, metrics.targets); nodeWeights.set(index, nodeMetrics); } return nodeMetrics; }
/** Finds the TCP address of the target. @return Returns a hop representing the TCP address of the target, or null if none could be found. */ LoadBalancer.Node getRecipient(RoutingContext context) { Mirror.Entry [] lastLookup = lookup(context, pattern); return loadBalancer.getRecipient(lastLookup); }
/** * The load balancing operation: Returns a node choice from the given choices, * based on previously gathered statistics on the nodes, and a running "position" * which is increased by 1 on each call to this. * * @param choices the node choices, represented as Slobrok entries * @return the chosen node, or null only if the given choices were zero */ public Node getRecipient(Mirror.Entry[] choices) { if (choices.length == 0) return null; double weightSum = 0.0; Node selectedNode = null; for (Mirror.Entry entry : choices) { NodeMetrics nodeMetrics = getNodeMetrics(entry); weightSum += nodeMetrics.weight.get(); if (weightSum > position) { selectedNode = new Node(entry, nodeMetrics); break; } } if (selectedNode == null) { // Position>sum of all weights: Wrap around (but keep the remainder for some reason) position -= weightSum; selectedNode = new Node(choices[0], getNodeMetrics(choices[0])); } position += 1.0; selectedNode.metrics.sent.inc(1); return selectedNode; }
public void received(Node node, boolean busy) { if (busy) { double wantWeight = node.metrics.weight.get() - 0.01; if (wantWeight < 1.0) { increaseWeights(); node.metrics.weight.set(1.0); } else { node.metrics.weight.set(wantWeight); } node.metrics.busy.inc(1); } }
public void merge(RoutingContext context) { RoutingNodeIterator it = context.getChildIterator(); Reply reply = it.removeReply(); LoadBalancer.Node target = (LoadBalancer.Node)context.getContext(); boolean busy = false; for (int i = 0; i < reply.getNumErrors(); i++) { if (reply.getError(i).getCode() == ErrorCode.SESSION_BUSY) { busy = true; } } loadBalancer.received(target, busy); context.setReply(reply); }