4 Replies Latest reply on Jan 31, 2013 3:36 PM by Paul Ferraro

    How to create and use my own distributed locks?

    Dave Rathnow Novice

      We are planning to run a cluster of JBoss AS7 servers that accept data from, and send data to, remote devices.  These devices are industrial monitoring devices that collect data from oil and gas wells.  Handling incoming data is simple since we can easily distribute the connection requests to the server instances in the cluster.  However, the outgoing part is bit more complicated because only one server can send data to a remote device at any given time.  To maintain high availability, outgoing data is delivered to all servers via a JMS topic and from there, the servers need to decide which one will send the data.  If any one of the servers goes down, we want the other servers in the cluster to take over without any human intervention.

       

      My thought was to use JGroups distributed locking feature to create a named Lock, something like "device@<ip-address>", and then call "tryLock" to see if the lock can be aquired.  If so, then the server that gets the lock takes responsibility for sending the data. If not, then it assumes one of the other server nodes will deal with it.

       

      I've been searching high and low to find examples of how to use the JGroups Distributed Lock manager from inside JBoss but so far I haven't found anything.  The only example I've been able to find has come from the JGroups documentation, which looks something like this:

       

      JChannel jchannel = JChannel("/home/bela/locking.xml");

      LockService lockService = new LockService(jchannel);

      jchannel.connect("lock-cluster");

      Lock lock=lock_service.getLock("device@.1.2.3.4");

      if (lock.tryLock())

                try {

                          // Send outgoing data

                } finally {

                          lock.unlock();

                }

       

      However, this isn't going to work with JBoss since JGroup's configuration is all done in domain.xml.

       

      So I have the following questions:

       

      1. Will the approach I'm proposing work?

       

      2. How can I get JChannel from application running inside the JBoss container?  Is there a way to inject a JChannel or do I have to look it up?

       

      3. In the example above, I'm not sure what the jchannel.connect("lock-cluster") is doing.  Is it needed from inside JBoss? What is the "lock-cluster" name?

        • 1. Re: How to create and use my own distributed locks?
          Bela Ban Master

          On how to grab a JChannel, there was a post by Paul which should be found using google (I don't know how to do this myself).

           

          Locking might work, but IMO a more elegant approach would be to send the messages to everyone (which you plan to do anyway) and then use hashing to decide which member should forward which messages to the devices. Once the task is done, a REMOVE message is sent and everyone removes the message(s) in it. When a member fails, every member computes a new hash for all messages in its queue and then forwards the messages it is now (newly) responsible for.

           

          This is completely peer-to-peer without a single point of failure. Plus, the task of message forwarding is distributed among the cluster members based on a consistent (hashing) algorithm.

           

          See [1] for details of a similar approach for task distribution.

          Cheers,

           

          [1] http://www.jgroups.org/taskdistribution.html

          1 of 1 people found this helpful
          • 2. Re: How to create and use my own distributed locks?
            Dave Rathnow Novice

            Thanks.  That helps.

             

            But, do you have any insight into the second question?  That is, how to obtain a JChannel (or Channel) from within my app? 

            • 3. Re: How to create and use my own distributed locks?
              Dave Rathnow Novice

              Well, I'm not sure who Paul is (Paul Ferraro perhaps) but if you're out there, could you help me out?  I've been searching for a couple of days now and can't find the answer to the question: how do you get a JChannel from inside a JBoss Session Bean (Stateful/Stateless/Singleton)?  I've managed to get a ServiceName object for "jboss.jgroups.stack.udp" but how to turn that into a JChannel?

               

              Or maybe I'm going about this all wrong.  All the JGroups documentation says that I have to create a JChannel by passing a configuration object (file, inputstream, url, etc.) to the constructor.  I was assuming that I had to use the JGroups configuration from the domain.xml (or standalone.xml) file specified by the <subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="udp">  element. 

               

              However, now I'm wondering if this isn't the case.  Do I have to create my own configuration file and build my own protocol stack?