I have a JEE6 application that runs on an Glassfish 3.1.2 cluster. One @Singleton Bean contains some kind of (readolny) cache. A User can press a button in the GUI to update the cache with (updated) content from the database.
This works well in a none clustered environment, but now we need to switch to an cluster.
So I am facing the problem, that when a user press that update button, only the Cache Singleton from his server node is updated. My question is, what would be the easiest way to make the other Singletons (in the other nodes) updating there data too?
I am aware of question Singleton in Cluster environment, but my question is specific for Glassfish (because I hope there is some build in support), the other one is taged with "Websphere". And my question is about JEE6, the other one is older than JEE6.
The simplest approaches are: Add an expiry timer to your singleton cache so that every so often the cache gets purged and subsquent calls fetch the updated data from source (e.g. a database) Implement a notification mechanism for the cache using something like a JMS topic/tibRV.
A cluster-singleton is a service that is deployed across multiple cluster nodes, which is never active in more than one node concurrently.
GlassFish High Availability Administration Guide explicitly states:
Restrictions
When configuring session persistence and failover, note the following restrictions:
When a session fails over, any references to open files or network connections are lost. Applications must be coded with this restriction in mind.
EJB Singletons are created for each server instance in a cluster, and not once per cluster.
Another suggestion, would be to use JMS and have the GUI button press post a message to a JMS Topic. All the Singleton beans can subscribe to that Topic and receiving the message will cause them all to update from the database, almost simultaneously. The benefit of this approach, is that it leverages more of the built in features of Glassfish, without necessarily having to bring in another framework.
In any case, moving from single instance to multiple instance is never a truly seamless change, and is going to cause some difficulty. There will probably need to be application changes to make sure that all the relevant state (other than session state), is shared correctly to all instances in the cluster.
Unfortunately there's no built-in way of achieving what you want, but the shoal framework that Glassfish bases its clustering on could help you out here. You can solve the problem either by sending notifications to cluster members to update their caches or by replacing your current cache with a distributed one.
Below is an example using shoal to send notifications:
@Startup
@Singleton
public class Test {
private String groupName = "mygroup";
private String serverName = System.getProperty("HTTP_LISTENER_PORT");
private GroupManagementService gms;
@PostConstruct
public void init() {
Runnable gmsRunnable = GMSFactory.startGMSModule(serverName, groupName,
GroupManagementService.MemberType.CORE, null);
gms = (GroupManagementService) gmsRunnable;
try {
gms.join();
gms.addActionFactory(new MessageActionFactory() {
@Override
public Action produceAction() {
return new MessageAction() {
@Override
public void consumeSignal(Signal signal)
throws ActionException {
// Update your cache here
}
};
}
}, groupName);
} catch (GMSException e) {
Logger.getAnonymousLogger().severe(e.getMessage());
}
}
@PreDestroy
public void cleanup() {
gms.shutdown(GMSConstants.shutdownType.INSTANCE_SHUTDOWN);
}
/**
* Call this from your button click.
*/
public void updateCache() {
try {
byte[] message = new byte[] {};
gms.getGroupHandle().sendMessage(groupName, message);
} catch (GMSException e) {
Logger.getAnonymousLogger().severe(e.getMessage());
}
}
}
If you wanted to use a distributed cache instead:
DistributedStateCache cache = gms.getGroupHandle().getDistributedStateCache();
Items placed in the cache will be replicated to the other cluster nodes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With