You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by ru...@apache.org on 2008/06/24 06:53:00 UTC
svn commit: r671024 - in /synapse/trunk/java:
modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/
modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/utils/
modules/core/src/main/java/org/apache/synapse/endpoints/ modules...
Author: ruwan
Date: Mon Jun 23 21:53:00 2008
New Revision: 671024
URL: http://svn.apache.org/viewvc?rev=671024&view=rev
Log:
Committing for azeez, (SYNAPSE-372)
Added:
synapse/trunk/java/repository/conf/sample/synapse_sample_58.xml
Modified:
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/LoadbalanceEndpointFactory.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/utils/LoadbalanceAlgorithmFactory.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/algorithms/RoundRobin.java
synapse/trunk/java/src/site/xdoc/Synapse_Samples.xml
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/LoadbalanceEndpointFactory.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/LoadbalanceEndpointFactory.java?rev=671024&r1=671023&r2=671024&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/LoadbalanceEndpointFactory.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/LoadbalanceEndpointFactory.java Mon Jun 23 21:53:00 2008
@@ -21,29 +21,36 @@
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
+import org.apache.axis2.clustering.Member;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.config.xml.endpoints.utils.LoadbalanceAlgorithmFactory;
+import org.apache.synapse.config.xml.XMLConfigConstants;
import org.apache.synapse.endpoints.Endpoint;
import org.apache.synapse.endpoints.LoadbalanceEndpoint;
import org.apache.synapse.endpoints.algorithms.LoadbalanceAlgorithm;
import javax.xml.namespace.QName;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
/**
* Creates {@link LoadbalanceEndpoint} using an XML configuration.
- *
+ * <p/>
* <endpoint [name="name"]>
- * <loadbalance policy="load balance algorithm">
- * <endpoint>+
- * </loadbalance>
+ * <loadbalance policy="load balance algorithm">
+ * <endpoint>+
+ * </loadbalance>
* </endpoint>
*/
public class LoadbalanceEndpointFactory extends EndpointFactory {
private static LoadbalanceEndpointFactory instance = new LoadbalanceEndpointFactory();
+ private static final QName MEMBER = new QName(SynapseConstants.SYNAPSE_NAMESPACE,
+ "member");
- private LoadbalanceEndpointFactory() {}
+ private LoadbalanceEndpointFactory() {
+ }
public static LoadbalanceEndpointFactory getInstance() {
return instance;
@@ -56,7 +63,7 @@
OMElement loadbalanceElement = epConfig.getFirstChildWithName(
new QName(SynapseConstants.SYNAPSE_NAMESPACE, "loadbalance"));
- if(loadbalanceElement != null) {
+ if (loadbalanceElement != null) {
LoadbalanceEndpoint loadbalanceEndpoint = new LoadbalanceEndpoint();
@@ -68,13 +75,26 @@
loadbalanceEndpoint.setName(name.getAttributeValue());
}
- // set endpoints
- ArrayList<Endpoint> endpoints = getEndpoints(loadbalanceElement, loadbalanceEndpoint);
- loadbalanceEndpoint.setEndpoints(endpoints);
+ LoadbalanceAlgorithm algorithm = null;
+
+ // set endpoints or members
+ if (loadbalanceElement.getFirstChildWithName(XMLConfigConstants.ENDPOINT_ELT) != null) {
+ ArrayList<Endpoint> endpoints
+ = getEndpoints(loadbalanceElement, loadbalanceEndpoint);
+ loadbalanceEndpoint.setEndpoints(endpoints);
+ algorithm =
+ LoadbalanceAlgorithmFactory.
+ createLoadbalanceAlgorithm(loadbalanceElement, endpoints);
+ } else if (loadbalanceElement.getFirstChildWithName(MEMBER) != null) {
+ List<Member> members = getMembers(loadbalanceElement);
+ loadbalanceEndpoint.setMembers(members);
+ algorithm =
+ LoadbalanceAlgorithmFactory.
+ createLoadbalanceAlgorithm2(loadbalanceElement, members);
+ loadbalanceEndpoint.startApplicationMembershipTimer();
+ }
// set load balance algorithm
- LoadbalanceAlgorithm algorithm = LoadbalanceAlgorithmFactory.
- createLoadbalanceAlgorithm(loadbalanceElement, endpoints);
loadbalanceEndpoint.setAlgorithm(algorithm);
// set if failover is turned off
@@ -88,4 +108,23 @@
return null; //To change body of implemented methods use File | Settings | File Templates.
}
+
+ private List<Member> getMembers(OMElement loadbalanceElement) {
+ List<Member> members = new ArrayList<Member>();
+ for(Iterator memberIter = loadbalanceElement.getChildrenWithName(MEMBER);
+ memberIter.hasNext();){
+ OMElement memberEle = (OMElement) memberIter.next();
+ Member member = new Member(memberEle.getAttributeValue(new QName("ip")), -1);
+ String http = memberEle.getAttributeValue(new QName("httpPort"));
+ if (http != null) {
+ member.setHttpPort(Integer.parseInt(http));
+ }
+ String https = memberEle.getAttributeValue(new QName("httpsPort"));
+ if (https != null && https.trim().length() != 0) {
+ member.setHttpsPort(Integer.parseInt(https.trim()));
+ }
+ members.add(member);
+ }
+ return members;
+ }
}
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/utils/LoadbalanceAlgorithmFactory.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/utils/LoadbalanceAlgorithmFactory.java?rev=671024&r1=671023&r2=671024&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/utils/LoadbalanceAlgorithmFactory.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/endpoints/utils/LoadbalanceAlgorithmFactory.java Mon Jun 23 21:53:00 2008
@@ -19,14 +19,16 @@
package org.apache.synapse.config.xml.endpoints.utils;
-import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.clustering.Member;
+import org.apache.synapse.config.xml.XMLConfigConstants;
import org.apache.synapse.endpoints.algorithms.LoadbalanceAlgorithm;
import org.apache.synapse.endpoints.algorithms.RoundRobin;
-import org.apache.synapse.config.xml.XMLConfigConstants;
import javax.xml.namespace.QName;
import java.util.ArrayList;
+import java.util.List;
/**
* Factory of all load balance algorithms. ESBSendMediatorFactroy will use this to create the
@@ -35,19 +37,37 @@
public class LoadbalanceAlgorithmFactory {
public static LoadbalanceAlgorithm createLoadbalanceAlgorithm(OMElement loadbalanceElement,
- ArrayList endpoints) {
+ ArrayList endpoints) {
+ LoadbalanceAlgorithm algorithm = null;
+ String algorithmName = "roundRobin";
+ OMAttribute algoAttribute =
+ loadbalanceElement.getAttribute(new QName(null, XMLConfigConstants.ALGORITHM_NAME));
+ if(algoAttribute != null) {
+ algorithmName = algoAttribute.getAttributeValue();
+ }
+
+ if (algorithmName.equalsIgnoreCase("roundRobin")) {
+ algorithm = new RoundRobin(endpoints);
+ }
+
+ return algorithm;
+ }
+
+ public static LoadbalanceAlgorithm createLoadbalanceAlgorithm2(OMElement loadbalanceElement,
+ List<Member> members) {
LoadbalanceAlgorithm algorithm = null;
String algorithmName = "roundRobin";
- OMAttribute algoAttribute = loadbalanceElement.getAttribute(new QName(
- null, XMLConfigConstants.ALGORITHM_NAME));
- if(algoAttribute != null) {
+ OMAttribute algoAttribute =
+ loadbalanceElement.getAttribute(new QName(null, XMLConfigConstants.ALGORITHM_NAME));
+ if (algoAttribute != null) {
algorithmName = algoAttribute.getAttributeValue();
}
- if(algorithmName.equalsIgnoreCase("roundRobin")) {
- algorithm = new RoundRobin(endpoints);
+ if (algorithmName.equalsIgnoreCase("roundRobin")) {
+ algorithm = new RoundRobin();
+ algorithm.setApplicationMembers(members);
}
return algorithm;
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java?rev=671024&r1=671023&r2=671024&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/LoadbalanceEndpoint.java Mon Jun 23 21:53:00 2008
@@ -19,18 +19,32 @@
package org.apache.synapse.endpoints;
+import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.clustering.ClusterManager;
+import org.apache.axis2.clustering.Member;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.FaultHandler;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
+import org.apache.synapse.SynapseException;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.endpoints.algorithms.AlgorithmContext;
import org.apache.synapse.endpoints.algorithms.LoadbalanceAlgorithm;
+import org.apache.synapse.endpoints.utils.EndpointDefinition;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
import java.util.List;
+import java.util.TimerTask;
+import java.util.Timer;
+import java.util.ArrayList;
+import java.io.IOException;
/**
* Load balance endpoint can have multiple endpoints. It will route messages according to the
@@ -57,6 +71,16 @@
private List<Endpoint> endpoints = null;
/**
+ * List of currently available application members amongst which the load is distributed
+ */
+ private List<Member> activeMembers = null;
+
+ /**
+ * List of currently unavailable members
+ */
+ private List<Member> inactiveMembers = null;
+
+ /**
* Algorithm used for selecting the next endpoint to direct the load. Default is RoundRobin.
*/
private LoadbalanceAlgorithm algorithm = null;
@@ -84,6 +108,11 @@
*/
private final AlgorithmContext algorithmContext = new AlgorithmContext();
+ public void startApplicationMembershipTimer(){
+ Timer timer = new Timer();
+ timer.scheduleAtFixedRate(new MemberActivatorTask(), 1000, 500);
+ }
+
public void send(MessageContext synMessageContext) {
if (log.isDebugEnabled()) {
@@ -131,6 +160,19 @@
}
}
+ if (endpoints != null) {
+ sendToEndpoint(synMessageContext);
+ } else if (activeMembers != null) {
+ EndpointReference to = synMessageContext.getTo();
+ LoadbalanceFaultHandler faultHandler = new LoadbalanceFaultHandler(to);
+ if (failover) {
+ synMessageContext.pushFaultHandler(faultHandler);
+ }
+ sendToApplicationMember(synMessageContext, to, faultHandler);
+ }
+ }
+
+ private void sendToEndpoint(MessageContext synMessageContext) {
Endpoint endpoint = algorithm.getNextEndpoint(synMessageContext, algorithmContext);
if (endpoint != null) {
@@ -158,6 +200,54 @@
}
}
+ private void sendToApplicationMember(MessageContext synCtx,
+ EndpointReference to,
+ LoadbalanceFaultHandler faultHandler) {
+ org.apache.axis2.context.MessageContext axis2MsgCtx =
+ ((Axis2MessageContext) synCtx).getAxis2MessageContext();
+
+ String transport = axis2MsgCtx.getTransportIn().getName();
+ algorithm.setApplicationMembers(activeMembers);
+ Member currentMember = algorithm.getNextApplicationMember(algorithmContext);
+ faultHandler.setCurrentMember(currentMember);
+
+ if (currentMember != null) {
+
+ // URL rewrite
+ if (transport.equals("http") || transport.equals("https")) {
+ String address = to.getAddress();
+ if (address.indexOf(":") != -1) {
+ try {
+ address = new URL(address).getPath();
+ } catch (MalformedURLException e) {
+ String msg = "URL " + address + " is malformed";
+ log.error(msg, e);
+ throw new SynapseException(msg, e);
+ }
+ }
+ EndpointReference epr =
+ new EndpointReference(transport + "://" + currentMember.getHostName() +
+ ":" + currentMember.getHttpPort() + address);
+ synCtx.setTo(epr);
+ if (failover) {
+ synCtx.getEnvelope().build();
+ }
+
+ AddressEndpoint endpoint = new AddressEndpoint();
+ EndpointDefinition definition = new EndpointDefinition();
+ endpoint.setEndpoint(definition);
+ endpoint.send(synCtx);
+ } else {
+ log.error("Cannot load balance for non-HTTP/S transport " + transport);
+ }
+ } else {
+ synCtx.getFaultStack().pop(); // Remove the LoadbalanceFaultHandler
+ String msg = "No application members available";
+ log.error(msg);
+ throw new SynapseException(msg);
+ }
+ }
+
public String getName() {
return name;
}
@@ -174,6 +264,11 @@
this.algorithm = algorithm;
}
+ public void setMembers(List<Member> members) {
+ this.activeMembers = members;
+ this.inactiveMembers = new ArrayList<Member>();
+ }
+
/**
* If this endpoint is in inactive state, checks if all immediate child endpoints are still
* failed. If so returns false. If at least one child endpoint is in active state, sets this
@@ -246,4 +341,95 @@
}
}
}
+
+ /**
+ * This FaultHandler will try to resend the message to another member if an error occurs
+ * while sending to some member. This is a failover mechanism
+ */
+ private class LoadbalanceFaultHandler extends FaultHandler {
+
+ private EndpointReference to;
+ private Member currentMember;
+
+ public void setCurrentMember(Member currentMember) {
+ this.currentMember = currentMember;
+ }
+
+ private LoadbalanceFaultHandler(EndpointReference to) {
+ this.to = to;
+ }
+
+ public void onFault(MessageContext synCtx) {
+ if (currentMember == null) {
+ return;
+ }
+ synCtx.pushFaultHandler(this);
+ activeMembers.remove(currentMember); // This member has to be inactivated
+ inactiveMembers.add(currentMember);
+ sendToApplicationMember(synCtx, to, this);
+ }
+ }
+
+ /**
+ * The task which checks whther inactive members have become available again
+ */
+ private class MemberActivatorTask extends TimerTask{
+
+ public void run() {
+ try {
+ for(Member member: inactiveMembers){
+ if(canConnect(member)){
+ inactiveMembers.remove(member);
+ activeMembers.add(member);
+ }
+ }
+ } catch (Exception ignored) {
+ // Ignore all exceptions. The timer should continue to run
+ }
+ }
+
+ /**
+ * Before activating a member, we will try to verify whether we can connect to it
+ *
+ * @param member The member whose connectvity needs to be verified
+ * @return true, if the member can be contacted; false, otherwise.
+ */
+ private boolean canConnect(Member member) {
+ if(log.isDebugEnabled()){
+ log.debug("Trying to connect to member " + member.getHostName() + "...");
+ }
+ for (int retries = 30; retries > 0; retries--) {
+ try {
+ InetAddress addr = InetAddress.getByName(member.getHostName());
+ int httpPort = member.getHttpPort();
+ if(log.isDebugEnabled()){
+ log.debug("HTTP Port=" + httpPort);
+ }
+ if (httpPort != -1) {
+ SocketAddress httpSockaddr = new InetSocketAddress(addr, httpPort);
+ new Socket().connect(httpSockaddr, 10000);
+ }
+ int httpsPort = member.getHttpsPort();
+ if(log.isDebugEnabled()){
+ log.debug("HTTPS Port=" + httpPort);
+ }
+ if (httpsPort != -1) {
+ SocketAddress httpsSockaddr = new InetSocketAddress(addr, httpsPort);
+ new Socket().connect(httpsSockaddr, 10000);
+ }
+ return true;
+ } catch (IOException e) {
+ if(log.isDebugEnabled()){
+ log.debug("", e);
+ }
+ String msg = e.getMessage();
+ if (msg.indexOf("Connection refused") == -1 &&
+ msg.indexOf("connect timed out") == -1) {
+ log.error("Cannot connect to member " + member, e);
+ }
+ }
+ }
+ return false;
+ }
+ }
}
Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/algorithms/RoundRobin.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/algorithms/RoundRobin.java?rev=671024&r1=671023&r2=671024&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/algorithms/RoundRobin.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/algorithms/RoundRobin.java Mon Jun 23 21:53:00 2008
@@ -41,12 +41,18 @@
*/
private ArrayList endpoints = null;
+ /**
+ * List of application members in the loadb balance group
+ */
private List<Member> members;
public RoundRobin(ArrayList endpoints) {
this.endpoints = endpoints;
}
+ public RoundRobin() {
+ }
+
public void setApplicationMembers(List<Member> members) {
this.members = members;
}
@@ -56,7 +62,7 @@
* available, returns null.
*
* @param synapseMessageContext MessageContext instance which holds all per-message properties
- * @param algorithmContext The context in which holds run time states related to the algorithm
+ * @param algorithmContext The context in which holds run time states related to the algorithm
* @return endpoint to send the next message
*/
public Endpoint getNextEndpoint(MessageContext synapseMessageContext,
Added: synapse/trunk/java/repository/conf/sample/synapse_sample_58.xml
URL: http://svn.apache.org/viewvc/synapse/trunk/java/repository/conf/sample/synapse_sample_58.xml?rev=671024&view=auto
==============================================================================
--- synapse/trunk/java/repository/conf/sample/synapse_sample_58.xml (added)
+++ synapse/trunk/java/repository/conf/sample/synapse_sample_58.xml Mon Jun 23 21:53:00 2008
@@ -0,0 +1,56 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<!-- Session less load balancing between 3 endpoints -->
+<definitions xmlns="http://ws.apache.org/ns/synapse">
+
+ <sequence name="main" onError="errorHandler">
+ <in>
+ <send>
+ <endpoint>
+ <loadbalance failover="true">
+ <member ip="127.0.0.1" httpPort="9001" httpsPort="9005"/>
+ <member ip="127.0.0.1" httpPort="9002" httpsPort="9006"/>
+ <member ip="127.0.0.1" httpPort="9003" httpsPort="9007"/>
+ </loadbalance>
+ </endpoint>
+ </send>
+ <drop/>
+ </in>
+
+ <out>
+ <!-- Send the messages where they have been sent (i.e. implicit To EPR) -->
+ <send/>
+ </out>
+ </sequence>
+
+ <sequence name="errorHandler">
+
+ <makefault>
+ <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
+ <reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
+ </makefault>
+
+ <header name="To" action="remove"/>
+ <property name="RESPONSE" value="true"/>
+
+ <send/>
+ </sequence>
+
+</definitions>
Modified: synapse/trunk/java/src/site/xdoc/Synapse_Samples.xml
URL: http://svn.apache.org/viewvc/synapse/trunk/java/src/site/xdoc/Synapse_Samples.xml?rev=671024&r1=671023&r2=671024&view=diff
==============================================================================
--- synapse/trunk/java/src/site/xdoc/Synapse_Samples.xml (original)
+++ synapse/trunk/java/src/site/xdoc/Synapse_Samples.xml Mon Jun 23 21:53:00 2008
@@ -218,6 +218,10 @@
<a href="#Sample57">Sample 57: Dynamic load balancing
between 3 nodes</a>
</li>
+ <li>
+ <a href="#Sample58">Sample 58: Static load balancing
+ between 3 nodes</a>
+ </li>
</ul>
</li>
<li>
@@ -2164,6 +2168,119 @@
all three servers.
</p>
+<h2>
+ <a name="Sample58" id="Sample58">Sample 58: Static load balancing between 3 nodes</a>
+ </h2>
+<pre xml:space="preserve">
+
+<definitions xmlns="http://ws.apache.org/ns/synapse">
+
+ <sequence name="main" onError="errorHandler">
+ <in>
+ <send>
+ <endpoint>
+ <loadbalance failover="true">
+ <member ip="127.0.0.1" httpPort="9001" httpsPort="9005"/>
+ <member ip="127.0.0.1" httpPort="9002" httpsPort="9006"/>
+ <member ip="127.0.0.1" httpPort="9003" httpsPort="9007"/>
+ </loadbalance>
+ </endpoint>
+ </send>
+ <drop/>
+ </in>
+
+ <out>
+ <send/>
+ </out>
+ </sequence>
+
+ <sequence name="errorHandler">
+
+ <makefault>
+ <code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
+ <reason value="COULDN'T SEND THE MESSAGE TO THE SERVER."/>
+ </makefault>
+
+ <header name="To" action="remove"/>
+ <property name="RESPONSE" value="true"/>
+
+ <send/>
+ </sequence>
+
+</definitions>
+
+</pre>
+ <p>
+ <strong>Objective: Demonstrate the simple static load balancing among a set of
+ nodes</strong>
+ </p>
+ <p>
+ <strong>Prerequisites:</strong>
+ </p>
+ <p>
+ Start Synapse with sample configuration 58. (i.e. synapse -sample 58)
+ </p>
+ <p>
+ Deploy the LoadbalanceFailoverService by switching to <Synapse
+ installation directory>/samples/axis2Server/src/LoadbalanceFailoverService
+ directory and running ant.
+ </p>
+ <p>
+ Start three instances of sample Axis2 server on HTTP ports 9001, 9002 and
+ 9003 and give some unique names to each server.
+ </p>
+ <p>
+ Example commands to run sample Axis2 servers from the <Synapse
+ installation directory>/samples/axis2Server directory in Linux are
+ listed below:
+ </p>
+<pre xml:space="preserve">./axis2server.sh -http 9001 -https 9005 -name MyServer1
+./axis2server.sh -http 9002 -https 9006 -name MyServer2
+./axis2server.sh -http 9003 -https 9007 -name MyServer3</pre>
+ <p>
+ Now we are done with setting up the environment for load balance sample.
+ Start the load balance and failover client using the following command:
+ </p>
+<pre xml:space="preserve">ant loadbalancefailover -Di=100</pre>
+ <p>
+ This client sends 100 requests to the LoadbalanceFailoverService through
+ Synapse. Synapse will distribute the load among the three nodes
+ mentioned in the configuration in a round-robin manner.
+ LoadbalanceFailoverService appends the name of the server to the response,
+ so that client can determine which server has processed the message. If
+ you examine the console output of the client, you can see that requests
+ are processed by three servers as follows:
+ </p>
+<pre xml:space="preserve">[java] Request: 1 ==> Response from server: MyServer1
+[java] Request: 2 ==> Response from server: MyServer2
+[java] Request: 3 ==> Response from server: MyServer3
+[java] Request: 4 ==> Response from server: MyServer1
+[java] Request: 5 ==> Response from server: MyServer2
+[java] Request: 6 ==> Response from server: MyServer3
+[java] Request: 7 ==> Response from server: MyServer1
+...</pre>
+ <p>
+ Now run the client without the -Di=100 parameter, i.e. ant loadbalancefailover,
+ to send infinite requests. While running the client shutdown the server named MyServer1.
+ You can observe that requests are only distributed among MyServer2 and
+ MyServer3 after shutting down MyServer1. Console output before and after
+ shutting down MyServer1 is listed below (MyServer1 was shutdown after
+ request 63):
+ </p>
+<pre xml:space="preserve">...
+[java] Request: 61 ==> Response from server: MyServer1
+[java] Request: 62 ==> Response from server: MyServer2
+[java] Request: 63 ==> Response from server: MyServer3
+[java] Request: 64 ==> Response from server: MyServer2
+[java] Request: 65 ==> Response from server: MyServer3
+[java] Request: 66 ==> Response from server: MyServer2
+[java] Request: 67 ==> Response from server: MyServer3
+...</pre>
+ <p>
+ Now restart MyServer1. You can observe that requests will be again sent to
+ all three servers.
+ </p>
+
<h1>
<a name="MessageMediationQoS" id="MessageMediationQoS">Quality of
Service addition or deduction samples in message mediation</a>