开发者

Why should I use JMS and not RMI+Queue?

At the moment I am using RMI or hessian library to communicate between my server and clients (via a LinkedBlockingQueue). Now I read about JMS which could be used in this area too. Is this correct? If yes, would you mind to give me a simple list of advantages/disadvantages, because it seems to be a pretty complicated and 'fullblown-enterprise' area.

What are the benefits? And what about the performance compared to RMI+Queue? Could JMS beat RMI+Queue?

PS: I know there are similar questions, but I would like to have JMS 开发者_StackOverflow中文版compared to RMI+Queue.


A simplified comparison would be (not particular to JMS, more like comparison against MQ in general)...

  1. Automatic retry
    If you are a client doing a RMI to a server and for some reason RMI fails, you have to try again yourself. If you'd use JMS and you are the client, you'd just send the JMS message. When the server can not be reached, your message will be stored and then delivered when the server is up again.

  2. Persistent queue
    Since you are using a LinkedBlockingQueue, you can either have a bounded queue or an unbounded queue in-memory. The former will start to trap threads once the queue is full and will eventually fail under high load. The later would eventually throw OutOfMemoryError instead. If you'd use JMS though, it can automatically start to "persist" messages to "persistent storage". Normally "persistent storage" is DB, which has usually much more capacity than in-memory queue. Of course, content of in-memory queue is lost when the server goes down etc., whereas in JMS you can choose durable message/persistent message that survives such event. This also allows you to have clustering, which is also very important for enterprise programs...

  3. Abstraction
    You'll be using a standardized API (ok, you have protocols in RMI too, but if what you want is passing around messages, MQ provides much more high level abstraction than RMI+in-memory queue). Which means, you get to use future implementations of JMS.. Perhaps something that doesn't need a DB to provide durability and persistence, more scalable than today's implementation etc. Or maybe you can send the same message to completely different service, because of the standerization. Basically, the higher abstraction could give you flexibility, that RMI+in-memory queue doesn't.

Some time ago, I worked with a big company that wanted to use their in-house framework to integrate our stuff. At that time we weren't using a MQ. We asked them to use our own asynchronous protocol based on RMI. Trust me, we regretted that decision very, very much...


The other answers cover many aspect of JMS, but I feel a very important one needs more emphasis, namely the fact that JMS supports multiple concurrent consumers in a transacted way. This is to me the killer feature.

  1. You can easily build a system with a single consumer and producer that is non-transacted.
  2. You can also make it (more or less) transactional with a bit more work.
  3. Similarly, you can add support for multiple producer and single consumer relatively easily, e.g., if you use a transactional database to store the message.
  4. But it becomes very hard to have multiple concurrent consumer and have message consumption be transactional. This basically require a non-trivial locking scheme, and even with the usage of a transactional database the task is not easy.

When we speak of JMS scalability, we however speak of this: the ability of the app. server to add/remove consumer/producer to manage the load.

Other advantages of JMS are quality of service and management, e.g. redelivery attempt, dead message queue, monitoring, etc.

If you don't really need that, a somewhat simpler solution might work. You can also see an other answer of mine where I cover a similar question: Why choosing JMS for asynchronous solution ?


What are you using for the "Queue" part of your solution? Your own code?

JMS is just an API above some vendor's queuing system, but one that incorporates the remoting aspects. So from client perspective you just put a message on a queue (or topic if you are doing pub sub), and forget about it. The infrastructure delivers it to the listener(s).

I see much of the power of JMS coming from the quality of implementation of the queuing infrastructure rather than the API itself, that's pretty simple.

Simple RMI doesn't scale well or deal with reliability concerns, a good queuing system can be both scalable and resilience.

I think it's fair to say that JMS and the rest of Java EE is intended to allow your application to be enterprise quality. Initially I think Java EE overal was complex, though I thought JMS was one of the simpler corners. Today, I'm not sure that writing RMI + your own queuing is any easier than just using JMS.

Possibly a significant difference is that using JMS pretty much assumes that you have some infrastructure such as an App Server in place.


JMS is transactional, can be coordinated with database transactions.
JMS Decouples the producers and consumers, meaning they do not need to be running at the same time.
JMS Is guaranteed delivery, meaning that the messages are guaranteed to get there, in case of a failure (Depending on failure type might require clustering).
JMS Can do Synchronous, Asynchronous point to point as well as Publish/Subscribe.
Most JMS implementations use a Queueing System that can work with other languages, OSes.


'Automatic retry If you are a client doing a RMI to a server and for some reason RMI fails, you have to try again yourself. If you'd use JMS and you are the client, you'd just send the JMS message. When the server can not be reached, your message will be stored and then delivered when the server is up again. '

I think answer is misleading. It's resilient in the sense messages sent to a destination for which they are no consumers will be stored until there is a consumer for that message or that message expires. This assumes that the JMS broker is viable.

If you try to send a message to a broker which is unreachable then you should get a JMSException and in that sense you're client messages may be lost unless your application makes some proviso to store them itself and retry. In this sense a client to a JMS server behaves the same as the client to a RMI server. You'll still lose the message if that server is down.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜