Using HA Singleton in JBoss 7
Some time ago I had to change standard clustering behavior of Quartz Scheduler, and let it work without synchronizing over database. There are of course a lot of options to do that, but because I'm big fan of simplicity I've decided to use standard Spring @Scheduled configuration and totally skip thinking about cluster at this level. The idea was to just invoke "check that I'm on master node" method at the beginning of the scheduled method. The only problem was how to write such method :) The choice was to use JBoss HA Singleton functionality. It's available in JBoss 7.x but the big lack of documentation forces some experiments... nice!
First thing which we need to do is to provide proper dependency, containing few important classes. Of course remember about right version (here I'm using 7.1.1.Final because it's available in public repositories and all next versions of 7 needs to be build manually).
package com.stackholder.jboss.ha;
First thing which we need to do is to provide proper dependency, containing few important classes. Of course remember about right version (here I'm using 7.1.1.Final because it's available in public repositories and all next versions of 7 needs to be build manually).
Now it's time to do some coding! Let's start from class containing service that will be installed into application server. Its role is to set master status flag and expose it by simple static method.org.jboss.as jboss-as-clustering-singleton 7.1.1.Final provided
package com.stackholder.jboss.ha;
import org.jboss.msc.service.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.concurrent.atomic.AtomicBoolean; public class MasterStatusHaSingleton extends AbstractService<Serializable> { private static final Logger LOGGER = LoggerFactory.getLogger(MasterStatusHaSingleton.class); private static AtomicBoolean masterStatus = new AtomicBoolean(false); @Override public void start(StartContext startContext) { LOGGER.info("MasterStatusHaSingleton started"); masterStatus.set(true); } @Override public void stop(StopContext stopContext) { LOGGER.info("MasterStatusHaSingleton stopped"); masterStatus.set(false); } public static boolean isMaster() { return masterStatus.get(); } }Now we need to write class that will install prepared service into container.
package com.stackholder.jboss.ha; import org.jboss.as.clustering.singleton.SingletonService; import org.jboss.msc.service.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HaSingletonActivator implements ServiceActivator { private final static Logger LOGGER = LoggerFactory.getLogger(HaSingletonActivator.class); public static final ServiceName SINGLETON_SERVICE_NAME = ServiceName.JBOSS.append("ha", "singleton"); @Override public void activate(ServiceActivatorContext context) throws ServiceRegistryException { LOGGER.info("HaSingletonActivator will be installed"); MasterStatusHaSingleton srv = new MasterStatusHaSingleton(); SingletonService singleton = new SingletonService(srv, SINGLETON_SERVICE_NAME); singleton.build(new DelegatingServiceContainer( context.getServiceTarget(),context.getServiceRegistry())) .setInitialMode(ServiceController.Mode.ACTIVE).install(); LOGGER.info("HaSingletonActivator installation SUCCESSFUL"); } }Remember that JBoss 7 is using OSGi, so we've to tell application server what modules we're going to use in our application. The easiest way to do that is to add configuration into war or jar plugin:
Last thing we need to do in our application is to include our ServiceActivator in JBoss. To do that we need to create file org.jboss.msc.service.ServiceActivator in META-INF directory. Content is just one line with our ServiceActivator qualified name, which in my case means:org.jboss.msc,org.jboss.as.server, org.jboss.as.clustering.singleton
com.stackholder.jboss.ha.HaSingletonActivatorGreat - almost finished! Almost :) Last thing we have to do is to activate proper modules in JBoss configuration. Just edit standalone-full-ha.xml file (or other configuration that you use of course) and add following modules into ee subsystem:
And finally you can execute your server and enjoy new, cool functionality ;)<module name="org.jboss.msc" slot="main"> <module name="org.jboss.as.clustering.singleton" slot="main">
Comments
In that file you should add qualified name of your activator (in my case com.stackholder.jboss.ha.HaSingletonActivator). Please confirm that it works so I could extend by article.
However, I am getting another issue running the example now. The error is "Name segment is null for server" on singleton.build(new DelegatingServiceContainer( context.getServiceTarget(),context.getServiceRegistry())) .setInitialMode(ServiceController.Mode.ACTIVE).install();
You put a service name ServiceName.JBOSS.append("ha", "singleton"). Do I have to do some setup to use that name? Or, it could be anything I come up to use?
Thanks!
I would like to know if you have any aqcuillian or test cases for an HA Singleton and it's ServiceActivator
Thanks
Piwe
gia ve may bay di my
chuyến bay từ mỹ về việt nam
bay từ đức về việt nam mấy tiếng
vé máy bay từ nga về việt nam bao nhiêu
lịch bay từ anh về việt nam hôm nay
chuyến bay từ pháp về việt nam hôm nay
chi phí vé máy bay cho chuyên gia nước ngoài