aspose file tools*
The moose likes Distributed Java and the fly likes Using JMS for RPC Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Distributed Java
Bookmark "Using JMS for RPC" Watch "Using JMS for RPC" New topic
Author

Using JMS for RPC

Tobi Sasse
Greenhorn

Joined: Sep 09, 2009
Posts: 10
Hi guys, I have a basic question on how to use JMS for RPC purposes. Please excuse my smartphone's spelling... Let me introduce an example:

I do have two frontend servers (plain Java Applications) that Take Requests from Users. so there is request R1 on frontend Server F1.

Further I have an ActiveMQ Broker on another machine with two Queues: TO_BACKEND and TO_FRONTEND

Further there is a backend server B1 that Processes Requests from the frontend severs.

So the Flow is as follows: F1 and F2 listen on TO_FRONTEND. B1 listens on TO_BACKEND.

F1 receives a request and puts a Message containing R1 on TO_BACKEND Where B1 picke it up, Processes it and puts a reply message on TO_FRONTEND.

Question: how do i ensure that the reply Message gets routed to F1 and Not to F2? I am missing a routing concept/component. I do not want to create seperate queues for each frontend/backend server couple, as my servers are supposed to not know of each other (extremely loose coupled system).

Further I do not want to use JMS topics and have all listeners filtering for Messages that belong to them. This should be done by a routing component.

Can you point me to best practices/frameworks please?

Thanks a lot,
Tobi
William P O'Sullivan
Ranch Hand

Joined: Mar 28, 2012
Posts: 859

Well, you have a many-to-one type of problem then.

Multiple sources (FRONT_ENDs) feeding one BACKEND.
Now you want the BACKEND to determine which of the sources to send the response to.

Unless BACKEND can explicitly determine the source of the message, and route it back to the correct source,
I feel that you may have to set up internal queues on each front end server. The message itself may have
metadata associated with it that would allow you to identify the source, if not, then embed something in the body.

WP
Tobi Sasse
Greenhorn

Joined: Sep 09, 2009
Posts: 10
Exactly! I am thinking that there should be something which I could put on top of JMS which does the routing for me. Implementing routing and addressing by hand just feels wrong to me as I am probably not the first with the many-to-one problem. But I just can't find a good solution to this, probably because I employ the wrong keywords on google. Happy for all advices!
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Tobi Sasse wrote:Hi guys, I have a basic question on how to use JMS for RPC purposes. Please excuse my smartphone's spelling... Let me introduce an example:

I do have two frontend servers (plain Java Applications) that Take Requests from Users. so there is request R1 on frontend Server F1.

Further I have an ActiveMQ Broker on another machine with two Queues: TO_BACKEND and TO_FRONTEND

Further there is a backend server B1 that Processes Requests from the frontend severs.

So the Flow is as follows: F1 and F2 listen on TO_FRONTEND. B1 listens on TO_BACKEND.

F1 receives a request and puts a Message containing R1 on TO_BACKEND Where B1 picke it up, Processes it and puts a reply message on TO_FRONTEND.

Question: how do i ensure that the reply Message gets routed to F1 and Not to F2? I am missing a routing concept/component. I do not want to create seperate queues for each frontend/backend server couple, as my servers are supposed to not know of each other (extremely loose coupled system).

Further I do not want to use JMS topics and have all listeners filtering for Messages that belong to them. This should be done by a routing component.

Can you point me to best practices/frameworks please?

Thanks a lot,
Tobi



Unfortunately, that is one of the disadvantages with using JMS -- you are using the lowest common denominator of features. And even then, some messaging systems don't support some parts of JMS either.

Some messaging systems support a request/respond mode, which establishes the routing for the return trip. Some messaging systems provide a way to setup indexes, for some sort of sticky routing of messages from the queue -- but I don't think either option is exposed via JMS. I am afraid that your options are limited -- either setup a JMS topic and filter the responses, or setup many queues for the responses.

Henry

Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Tobi Sasse
Greenhorn

Joined: Sep 09, 2009
Posts: 10
Found something that might help in this situation, employed by Apache Camel: http://camel.apache.org/dynamic-router.html

If you would hold state of which sender expects which message (correlation id) the dynamic router might be able to choose the right receipient. Haven't tested it because I built a hand-made solution yesterday night which performs very well.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4659
    
    5

Why not just use JMS to send messages, and not bother with RPC at all?

I see no advantage of using RPC. Sending messages is much cleaner and easier.
Tobi Sasse
Greenhorn

Joined: Sep 09, 2009
Posts: 10
Pat Farrell wrote:Why not just use JMS to send messages, and not bother with RPC at all?

I see no advantage of using RPC. Sending messages is much cleaner and easier.


Pat, I used the term "RPC" for generic remote procedure calls, non implementation specific. The problem I was having with JMS-solo is that you are not able to address a specific consumer which listens on a queue. So if you have one producer that is sending a message to consumer X - there are only two options. Either send it to a topic and have all the other consumers (that are not X) filtering the message and determining "oh this message is for X and not for me so forget it" - which may cause some significant overhead on the consumers. Or to set up a private queue inbetween the producer and consumer x. The later approach would introduce some addressing problems, which aren't solved by plain JMS.

So in the end you need to have something on top of JMS if you want to solve these kind of problems - like a JMS Router which is presented by Apache Camel for instance. If I am missing something, please give me a hand. I am fairly new to JMS myself...
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4659
    
    5

Tobi Sasse wrote:Either send it to a topic and have all the other consumers (that are not X) filtering the message and determining "oh this message is for X and not for me so forget it" - which may cause some significant overhead on the consumers. Or to set up a private queue inbetween the producer and consumer x. The later approach would introduce some addressing problems, which aren't solved by plain JMS.


Your analysis is 100% correct.

The traditional solutions don't apply to many real world needs. A third approach is to send everything through a routing proxy, which just forwards it to the approved listeners. This begs a critical question: how do you identify the routing proxy so you know where to send the messages?

This is a key problem with all distributed systems. If you have a universal directory of where to send what, or who can receive it, then its a single point of failure and you still have to find the universal directory. Do you look it up in a universal-universal directory?

Eventually you give up and hard code the destinations.

Tobi Sasse
Greenhorn

Joined: Sep 09, 2009
Posts: 10
I came up with my own solution which tries to reduce hard coupling (having nodes knowing of each other in terms of connectivity) and the single point of failure (some kind of nameserver which gives queue destinations to each component) problem.

In the system I currently design we have a couple of clusters, which are either frontend services (like webservers) and backend services (like databases). Within each cluster, say a webserver cluster, there is a router component on which all cluster members (i want to be able to dynamically scale up and down clusters) register themselves, via a maintenance queue. The router component then assigns queues for the communication from and to the individual server. Once a cluster member sends a request to the backend it puts a message on the queue to the router, the router than tracks the message's correlation ID and forwards the request message to the backend. Queues to the backend are managed statically for the moment (like DATABASE_IN & DATABASE_OUT) but this will change in the future. It than listens for the answer on the appropriate queue and resolves the original sender who put the request by the correlation ID of the reply message. It than forwards the message to the original sender onto it's queue.

By this approach i can bridge syncronous requests (webserver waiting for query results) to the asyncronous (JMS) backend. Further I have a routing mechanism.

That's my thoughts on routing in JMS. Happy to hear your comments on my design.
 
Consider Paul's rocket mass heater.
 
subject: Using JMS for RPC