My understanding of Distributed Replicant Manager (DRM) is that it allows you to attach some serialized data (stub) to a cluster node and manage it.
Examples of this data include the list of stubs for a given RMI server. Each node has a stub to share with other nodes. The DRM enables the sharing of these stubs in the cluster, and allows one to know which node each stub belongs to.
In case one of the nodes leaves the cluster, its stub is automatically removed from the list of replicants (stubs) that DRM maintains.
Also for each set of replicants DRM holds an id, which is identical on all nodes in the cluster.
I used DRM to attach a replicant to a node in the cluster. The replicant contains a String which holds a node IP that i get from jboss.bind.address property. Every time my cluster is going through a topology changes, my service bean on the master node will prints out replicant list.
My service MBean as follows:
[java]
package com.example;
public class CoordinatorHAService extends
HASingletonSupport implements
CoordinatorHAServiceMBean {
private static Logger logger =
Logger.getLogger(CoordinatorHAService.class);
/**
* Can be used instead of the constructor
* defined in jboss-service.xml
*/
private static final String BIND_ADDRESS =
System.getProperty("jboss.bind.address");
/**
* Custom name for this HA partition, overrides
* the default HA partition name which is
* canonical name of this MBean
*/
private final static
String COORDINATOR_HA_SERVICE_NAME =
"ServiceName:CoordinatorHAService";
/**
* Current node IP
*/
private String nodeIp = null;
/**
* Constructor that gets value of this node IP
* from ‘jboss.bind.address’ property
* defined in jboss-service.xml
*
*/
public CoordinatorHAService(String nodeIp) {
this.nodeIp = nodeIp;
}
public void startService() throws Exception {
try {
/**
* Call for super must be done before getting
* HAPartition. If super is not called, HAPartition
* will be ‘null’
*
* Alternatively you can use InitialContext to get
* default partition, then you dont have to make
* a call for super.startService(). I havent
* tested it, so I am not sure of the results.
*
*
* InitialContext ic = new InitialContext();
* String partitionName = ServerConfigUtil.getDefaultPartitionName();
* String partitionJndi = "/HAPartition/" + partitionName;
* HAPartition partition = (HAPartition) ic.lookup(partitionJndi);
*/
super.startService();
/**
* HAPartition gives access to the replicant manager,
* which I am using to add node replicants to.
*/
HAPartition partition = super.getPartition();
if (partition != null) {
partition.getDistributedReplicantManager().add(
this.getServiceHAName(), this.getNodeIp());
}
} catch (Exception e) {
this.stopService();
}
}
synchronized public void stopService() throws Exception {
super.stopService();
}
public boolean isMasterNode() {
return super.isMasterNode();
}
/**
* Called when node is elected as a master node
*/
public void startSingleton() {
}
/**
* Called when node stops acting as a master node
*/
public void stopSingleton() {
}
/**
* Override this method only if you need to provide
* a custom partition wide unique service name.
* The default implementation will usually work,
* provided that the getServiceName() method returns
* a unique canonical MBean name.
*
*/
public String getServiceHAName() {
// return super.getServiceHAName();
return CoordinatorHAService.COORDINATOR_HA_SERVICE_NAME;
}
/**
* Called when there are topology changes in the cluster.
*/
public void partitionTopologyChanged(List newReplicants,
int newViewID) {
super.partitionTopologyChanged(newReplicants,
newViewID);
/**
* If current service is the master node -
* print replicants in the cluster
*/
if (this.isMasterNode()) {
List clusterNodeIps =
new LinkedList(newReplicants);
for (String clusterNodeIp : clusterNodeIps) {
logger.info("Replicant IP: " + clusterNodeIp);
}
}
}
/**
* Gets current node’s IP
*/
public String getNodeIp() {
return nodeIp;
}
}
[/java]
..and this is my jboss-service.xml below:
[xml]
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean
code="com.example.CoordinatorHAService"
name="com.example:service=CoordinatorHAService">
<constructor>
<arg type="java.lang.String"
value="${jboss.bind.address:127.0.0.1}" />
</constructor>
</mbean>
</server>
[/xml]
In JBoss clustering architecture, DRM sits on top of HAPartition which abstracts the communication framework.
Maybe this is not the most right way to do it, but I do find DRM useful if I want to manage information about my cluster nodes, and I dont want to rely on HAPartition to provide me with such information.
The moment a new node joins the cluster, I insert its IP to my set of replicants. So I always have accurate and recent information about nodes in my cluster. In case of a dead node, my list of replicants gets updated with IP of the dead node removed from the list. The source code is attached to this post or you can just do copy/paste if you feel like it.
JBoss clustering is a very big topic. So if someone is interested, JBoss group provides a PDF book called JBoss AS Clustering on their website, its really useful and easy to understand. It walks through and talks about fundamental concepts of clustering. The book is a bit long but worth while to have a look
Any comments or/and flames about this post are welcomed …
cheers