Wednesday, October 27, 2010

STOMP for JGroups

FYI,

I've written a new JGroups protocol STOMP, which implements the STOMP protocol. This allows for STOMP clients to connect to any JGroups server node (which has the JGroups STOMP protocol in its configuration).

The benefits of this are:
  •  Clients can be written in any language. For example, I've used stomppy, a Python client, to connect to JGroups server nodes, and successfully subscribed to destinations, and sent and received messages.
  • Sometimes, clients don't want to be peers, ie. they don't want to join a cluster and become full members. These (light-weight) clients could also be in a different geographic location, and not be able to use IP multicasting.
  • Clients are started and stopped frequently, and there might be many of them. Frequently starting and stopping a full-blown JGroups server node has a cost, and is not recommended. Besides, a high churn rate might move the cluster coordinator around quite a lot, preventing it from doing real work.
  • We can easily scale to a large number of clients. Although every client requires 1 thread on the server side, we can easily support hundreds of clients. Note though that I wouldn't use the current JGroups STOMP protocol to connect thousands of clients...
Let's take a quick look: I started an instance of JGroups with STOMP on the top of the protocol stack (on 192.168.1.5). Then I connected to it with the JGroups client:

JGroups STOMP client

As can be seen, the first response the client received was an INFO with information about the available endpoints (STOMP instances) in the cluster. This is actually used by the StompConnection client to failover to a different server node should the currently connected to server fail.
Next, we subscribe to destination /a using the simplified syntax of the JGroups STOMP client.

Then, a telnet session to 192.168.1.5:8787 was started:

Telnet STOMP client



We get the INFO response with the list of endpoints too here. Then we subscribe to the /a destination. Note that the syntax used here is compliant with the STOMP protocol spec: first is the verb (SUBSCRIBE), then an optional bunch of headers (here just one, defining the destination to subscribe to), a newline and finally the body, terminated with a 0 byte. (SUBSCRIBE does not have a body).

Next, we send a message to all clients subscribed to /a. This is the telnet session itself, as evidenced by the reception of MESSAGE. If you look at the JGroups STOMP client, the message is also received there.

Next the JGroups client also sends a message to destination /a, which is received by itself and the telnet client.

JGroups 2.11.0.Beta2 also ships with a 'stompified' Draw demo, org.jgroups.demos.StompDraw, which is a stripped down version of Draw, using the STOMP protocol to send updates to the cluster.

Let me know what you think of this; feature requests, feedback etc appreciated (preferably on one of the JGroups mailing lists) !



The new protocol is part of JGroups 2.11.0.Beta2, which can be downloaded here.

Documentation is here.

Enjoy !

7 comments:

  1. I don't understand what the STOMP protocol is. Is it for a specific application? Or does it let a Python client (and other languages) communicate with a JGroups server and does it support ALL JGroups functionality? Thanks

    ReplyDelete
  2. Check out http://stomp.codehaus.org. Yes, STOMP lets clients written in any language send messages to (unicast or multicast) destinations, and receive messages sent to those.
    No, only a small subset of the JGroups functionality is supported. In other words, this is *not* a port of JGroups to Python.
    Bela

    ReplyDelete
  3. Is there a document or page anywhere that lists the features that are supported and those that are not?

    ReplyDelete
  4. Hello Bela: Thanks so much for this product; it appears to be exactly what we need. I am having a problem, however. I am running a simple channel.send() test. One of the test clients is running on Linux (Ubuntu) and the other client is running on Windows 7. If I send a 46K message (actually I think any message larger than about 20K) from the Linux client, the Windows client receives it every time. However if I send the same 46K message from the Windows client to the Linux one, the message is never received. In fact, after the 46K message is sent, the Linux client doesn't seem to receive *any* message, no matter the size. I've tried using different configurations (default, flush-udp.xml, sequencer.xml, and a couple others) to get around this but nothing helps. Do you have any idea why I would see this kind of behavior?

    ReplyDelete
  5. Can you zip your config and sample program, plus steps to reproduce, and send it to me (belaban at yahoo dot com) so I can take a look ?
    Bela

    ReplyDelete
  6. Hello Bela: I have sent you an email that has the sample application (includes source and compiled classes) attached in a zip file. The subject line of the mail is "Code for Windows-to-Ubuntu communication problem (question that I asked on your blog)" I think I included enough details in the email for you to easily duplicate the problem I'm seeing.

    Please let me know if there is any other information I can supply.

    Thanks.

    ReplyDelete