Load Balancer PlugIn Developer Guide

 jWebSocket Load Balancer PlugIn Documentation (v1.0)
 
The jWebSocket Load Balancer plug-in offers to developers an amazing easy way to develop fully clustered, scalable and distributed endpoint services with automated load balancing mechanisms.
 Cuadro de texto:  Illustration 1: Services clusters on top of jWebSocket Server + Load Balancer plug-in.
Illustration 1: Services clusters on top of jWebSocket Server + Load Balancer plug-in.
 
 
Setting up the Load Balancer plug-in on the server
 
To setup the Load Balancer plug-in in order to be loaded at jWebSocket server runtime, it is necessary to add the following configuration on the <plugins></plugins> section of the jWebSocket.xml file:
 
<plugins>
  ... 
  <!-- jWebSocket Load Balancer plug-in -->
  <plugin>
    <name>org.jwebsocket.plugins.loadbalancer.LoadBalancerPlugIn</name>
    <id>jws.lb</id>
    <ns>org.jWebSocket.plugins.loadbalancer</ns>
    <jar>jWebSocketLoadBalancerPlugIn-1.0.jar</jar>
    <server-assignments>
      <server-assignment>ts0</server-assignment>
    </server-assignments>
    <settings>
      <setting key="spring_config">${JWEBSOCKET_HOME}conf/LoadBalancerPlugIn/loadbalancer.xml</setting>
      </settings>
   </plugin>
</plugins>
 
 
Note:
As we can notice, the spring configuration for the Load Balancer plug-in is located in the jWebSocket configuration directory '/LoadBalancerPlugIn/loadbalancer.xml'. Please have a look to the file and read in-line comments for a better understanding.
 
Also it is required to setup the Load Balancer filter that will be responsible of routing transparently incoming client requests to target services. To setup the filter please add the following configuration on the <filters></filters> section of the jWebSocket.xml file:
<filters>
  ... 
  
  <!-- jWebSocket Load Balancer filter -->
  <filter>
    <name>org.jwebsocket.plugins.loadbalancer.LoadBalancerFilter</name>
    <id>jws.loadBalancerFilter</id>
    <ns>org.jwebsocket.plugins.loadbalancer</ns>
    <jar>jWebSocketLoadBalancerPlugIn-1.0.jar</jar>
    <server-assignments>
      <server-assignment>ts0</server-assignment>
    </server-assignments>
    <settings>
      <!-- The identifier of the Load Balancer plug-in -->
      <setting key="loadbalancer_plugin_id">jws.lb</setting>
    </settings>
  </filter>
  ... 
</filters>
The Load Balancer plug-in API
The Load Balancer API is designed to easily allow remote service endpoints to register/deregister on target service clusters. Also to retrieve clusters information and change the balancing algorithm (for administrator clients).
 
 
Note:
Next versions of the Load Balancer plug-in will provide web based clusters management and monitoring tools among other features.
 
 
See the API below:
  • Getting service clusters information (intended to be an administrative feature): The server sends a list (of maps) with the in-formation about all clusters (e.g. per cluster: cluster-alias, number of end-points, list of endpoints in this cluster, status per endpoint etc.)
 
org.jwebsocket.plugins.loadbalancer.clustersInfo
 
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"clustersInfo"}
 
Example response token:
{"type":"response","code":0,"msg":"ok","utid":6,"ns":"org.jwebsocket.plugins.loadbalancer", "reqType":"clustersInfo", "data":[{"requests":0,"clusterAlias":"service1","endPointsCount":1,"endPoints":[{"id":"c5253544-2123-4310-a4e7-51a4e673e58c","status":"ONLINE","requests":0}],"clusterNS":"org.jwebsocket.plugins.sample1"},{"requests":0,"clusterAlias":"service2","endPointsCount":0,"endPoints":[],"clusterNS":"org.jwebsocket.plugins.sample2"},{"requests":0,"clusterAlias":"service3","endPointsCount":0,"endPoints":[],"clusterNS":"org.jwebsocket.plugins.sample3"}]}
 
Example usage (JavaScript client):
 
lClient.lbClustersInfo({
 OnSuccess: function(aResponse){}
});
 
 
Example usage (Java client):
 
LoadBalancerPlugIn lLBP = new LoadBalancerPlugIn(lClient);
lLBP.clustersInfo(new BaseTokenResponseListener(){
 
 @Override
 public void OnSuccess(Token aToken) {}
});
 
 
Example usage (JMS Gateway | JWSEndPoint):
           
Token lToken = 	TokenFactory.createToken("org.jwebsocket.plugins.loadbalancer", 	"clustersInfo");
	lJWSEndPoint.sendToken(lServerEndPointId, lToken);
 
  • Getting the clusters services sticky routes (intended to be an administrative feature): Sends a list of all sticky routes managed by the load balancer, consisting of cluster-alias, client endpoint-id, service endpoint-id.
Required role:
org.jwebsocket.plugins.loadbalancer.clustersInfo
 
Example request token:
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"stickyRoutes"}
 
 
Example response token:
{"type":"response","code":0,"msg":"ok","utid":15,"ns":"org.jwebsocket.plugins.loadbalancer", "reqType":"stickyRoutes", "data":[{"clusterAlias":"service1","endPointId":"c5253544-2123-4310-a4e7-51a4e673e58c"},{"clusterAlias":"service1","endPointId":"7ca87dc2-ce25-4cff-8648-e84fb7d67b3e"},{"clusterAlias":"service2","endPointId":"a7e61844-5d12-478c-b215-4194db191af5"}]}
 
 
 
lClient.lbStickyRoutes({
 OnSuccess: function(aResponse){}
});
 
 
Example usage (Java client):
 
LoadBalancerPlugIn lLBP = new LoadBalancerPlugIn(lClient);
lLBP.stickyRoutes(new BaseTokenResponseListener(){
 
 @Override
 public void OnSuccess(Token aToken) {}
});
 
 
Example usage (JMS Gateway | JWSEndPoint):
 
Token lToken = 	TokenFactory.createToken("org.jwebsocket.plugins.loadbalancer", 	"stickyRoutes");
	lJWSEndPoint.sendToken(lServerEndPointId, lToken);
 
 
Required role:
org.jwebsocket.plugins.loadbalancer.changeBalancerAlgorithm
 
Example request token:
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"changeAlgorithm", "algorithm": 1}
 
 
Example response token:
{"type":"response","code":0,"msg":"ok","utid":2,"ns":"org.jwebsocket.plugins.loadbalancer", "reqType":"changeAlgorithm","currentAlgorithm":"Round Robin [1]"}
 
 
lClient.lbChangeAlgorithm(1, {
 OnSuccess: function(aResponse){}
});
 
 
Example usage (Java client):
LoadBalancerPlugIn lLBP = new LoadBalancerPlugIn(lClient);
lLBP.changeAlgorithm(1, new BaseTokenResponseListener(){
 
 @Override
 public void OnSuccess(Token aToken) {}
});
 
 
Example usage (JMS Gateway | JWSEndPoint):
           
Token lToken =           TokenFactory.createToken("org.jwebsocket.plugins.loadbalancer",             "changeAlgorithm");
lToken.setInteger("algorithm", 1);           
lJWSEndPoint.sendToken(lServerEndPointId, lToken);
 
  • Register service endpoint on target cluster:  Register a new service endpoint on target service cluster.
 
Required role:
org.jwebsocket.plugins.loadbalancer.registerServiceEndPoint
 
Example request token:
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"registerServiceEndPoint", "clusterAlias": "service1", "password": "asdlk32jr234"}
 
 
Example response token:
{"type":"response","code":0,"msg":"ok","utid":5,"ns":"org.jwebsocket.plugins.loadbalancer", "reqType":"registerServiceEndPoint", "endPointId":"f0cdc4c4-8f86-4e7c-a73b-d1fe729b2c67"}
 
 
 
lClient.lbRegisterServiceEndPoint('service1', 'asdlk32jr234');
lClient.addPlugIn({
 processToken: function(aRequest){
    if ('cluster.namespace' ==  aRequest.ns){
      if ('operation.name' == aRequest.type){
        // do something
        // ...
        // send response if required
        var lResponse = lClient.lbCreateResponse(aRequest);
        lClient.sendToken(lResponse);
      } 
    }
 }
});
 
 
Example usage (Java client):
 
final WebSocketTokenClient lClient = getTokenClient();
lClient.addListener(new BaseServiceTokenPlugIn(getTokenClient(), aClusterNamespace) {
 
 @Override
 public void processToken(WebSocketClientEvent aEvent, Token aToken) {
    if (getNS().equals(aToken.getNS())) {
      try {
        if ("operation.name".equals(aToken.getType())) {
          // do something
          // ...
          Token lResponse = createResponse(aToken);
          getTokenClient().sendToken(lResponse);
        }
    } catch (WebSocketException lEx) {
      // handle exception
    }
 }
}});
 
lClient.registerServiceEndPoint(“service1”, “asdlk32jr234”, new BaseTokenResponseListener(){
 
 @Override
 public void OnSuccess(Token aToken) {
    // service registration successful
 }
 @Override
 public void OnResponse(Token aToken) {
    // service registration failed
 }
});
 
 
Example usage (JMS Gateway | JWSEndPoint):
 
// set the CPU usage updater for the instance (only once per endpoint id)
lCpuUpdater = new JWSLoadBalancerCpuUpdater(lJWSEndPoint, lServerEndPointId);
lCpuUpdater.autoStart();
 
// custom operations support
lJWSEndPoint.addRequestListener("cluster.ns", "operation.name", new JWSMessageListener(lJWSEndPoint) {
 
  @Override
  public void processToken(String aSourceId, Token aToken) {
    // do something
    // ...
    Token lResponse = Tools.createLoadBalancerResponse(aToken);
    lJWSEndPoint.sendToken(lServerEndPointId, lResponse);
  }
});
 
// custom operations support
lJWSEndPoint.addRequestListener("cluster.ns", "operation.name2", new JWSMessageListener(lJWSEndPoint) {
 
  @Override
  public void processToken(String aSourceId, Token aToken) {
    // do something
    // ...
    Token lResponse = Tools.createLoadBalancerResponse(aToken);
    lJWSEndPoint.sendToken(lServerEndPointId, lResponse);
  }
});
// finally registering the service endpoint
Token lToken = TokenFactory.createToken("org.jwebsocket.plugins.loadbalancer", "registerServiceEndPoint");
lToken.setString("clusterAlias", aClusterAlias);
lToken.setString("password", aPassword);
lJWSEndPoint.sendToken(lServerEndPointId, lToken);
  • Deregister service endpoint on target cluster:  De-registers a connected service endpoint. In case the endpoint is part of the load balancer configuration the internal entry in the table of end-points gets tagged as "de-registered". In case the endpoint was a dynamically added one the item in the internal table shall be removed. This method can be also used by an administration too, to restart a certain endpoint after an update.
 
Required role:
org.jwebsocket.plugins.loadbalancer.registerServiceEndPoint
 
Example request token:
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"deregisterServiceEndPoint", "clusterAlias": "service1", "password": "asdlk32jr234", "endPointId": "f0cdc4c4-8f86-4e7c-a73b-d1fe729b2c67"}
 
Example response token:
{"type":"response","code":0,"msg":"ok","utid":8,"ns":"org.jwebsocket.plugins.loadbalancer", "reqType":"deregisterServiceEndPoint"}
 
 
Sent event to endpoint client:
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"event","name":"serviceEndPointDeregistered", "endPointId":"2a742444-f9ba-400f-ac39-4720b3eca3d8","user":"root"}
 
 
 
lClient.lbDeregisterServiceEndPoint(aClusterAlias, aPassword, aEndPointId, {
 OnSuccess: function(aResponse){}
});
 
 
Example usage (Java client):
 
LoadBalancerPlugIn lLBP = new LoadBalancerPlugIn(lClient);
lLBP.deregisterServiceEndPoint(aClusterAlias, aPassword, aEndPointId, new BaseTokenResponseListener(){
 
 @Override
 public void OnSuccess(Token aToken) {}
});
 
 
Example usage (JMS Gateway | JWSEndPoint):
          
  Token lToken =           TokenFactory.createToken("org.jwebsocket.plugins.loadbalancer",             "deregisterServiceEndPoint");
lToken.setString("clusterAlias", aClusterAlias);
lToken.setString("password", aPassword);
lToken.setString("endPointId", aEndPointId);
            lJWSEndPoint.sendToken(lServerEndPointId, lToken);
 
  • Shutdown service endpoint on target cluster:  Sends a message to the referenced endpoint to gracefully shutdown. A graceful shutdown should include a clean de-registration from the load balancer plug-in. Since it can be not guaranteed that the target endpoint processes the shutdown request properly, the endpoint service is immediately removed. It is responsibility of the service endpoints to properly release active resources or finally close the connection with the server.
 
Required role:
org.jwebsocket.plugins.loadbalancer.shutdownEndPoint
 
Example request token:
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"shutdownServiceEndPoint", "clusterAlias": "service1", "password": "asdlk32jr234", "endPointId": "2a742444-f9ba-400f-ac39-4720b3eca3d8"}
 
 
Example response token:
{"type":"response","code":0,"msg":"ok","utid":7,"ns":"org.jwebsocket.plugins.loadbalancer", "reqType":"shutdownServiceEndPoint","endPointId":"2a742444-f9ba-400f-ac39-4720b3eca3d8"}
 
 
{"ns":"org.jwebsocket.plugins.loadbalancer","type":"event","name":"shutdownEndPoint", "endPointId":"2a742444-f9ba-400f-ac39-4720b3eca3d8","user":"root"}
 
 
 
lClient.lbShutdownEndPoint(aClusterAlias, aPassword, aEndPointId, {
 OnSuccess: function(aResponse){}
});
 
 
Example usage (Java client):
 
LoadBalancerPlugIn lLBP = new LoadBalancerPlugIn(lClient);
lLBP.shutdownEndPoint(aClusterAlias, aPassword, aEndPointId, new BaseTokenResponseListener(){
 
 @Override
 public void OnSuccess(Token aToken) {}
});
 
 
Example usage (JMS Gateway | JWSEndPoint):
           
Token lToken =           TokenFactory.createToken("org.jwebsocket.plugins.loadbalancer",             "shutdownServiceEndPoint");
lToken.setString("clusterAlias", aClusterAlias);
lToken.setString("password", aPassword);
lToken.setString("endPointId", aEndPointId);
            lJWSEndPoint.sendToken(lServerEndPointId, lToken);
 
 
The Load Balancer plug-in has been designed with distributed and high scalable environments in mind (see https://jwebsocket.org/documentation/installation-guide/jwebsocket-cluster).
By using the combination of jWebSocket server clusters as a solid and central message bus with the Load Balancer plug-in on top, developers can build amazing services networks with no single point of failure, being able to process millions of concurrent requests and connected clients.
 
Cuadro de texto:  Illustration 2: High performance and high availability cluster with jWebSocket Server and the LoadBalancer plug-in.
Illustration 2: High performance and high availability cluster with jWebSocket Server and the LoadBalancer plug-in.  
To work on distributed environments, the Load Balancer plug-in requires to store the cluster's data into persistent databases. For this case, developers require to configure the MongoDB clusters manager solution for persistent data storage.
 
Note:
Please see the Load Balancer plug-in configuration file, that is located in the jWebSocket configuration directory '/LoadBalancerPlugIn/loadbalancer.xml' for detailed in-line comments.
Automated tests
 
The jWebSocket Load Balancer plug-in comes with a set of automated tests to guarantee the correct features behavior over the continuous development and improvements.
 
Publications

Learn more about WebSockets in general, get background information and gain deeper insight!

Join jWebSocket

Wether developer, designer or translator – join the jWebSocket team and grow together with our success!

Copyright © 2013 Innotrade GmbH. All rights reserved.