为什么我应该使用 JMS 而不是 RMI+Queue?

发布于 2024-09-13 17:43:37 字数 555 浏览 7 评论 0原文

目前,我正在使用 RMI 或 hessian 库 在我的服务器和客户端之间进行通信(通过 LinkedBlockingQueue )。现在我读到了JMS,它也可以在这个领域使用。这是正确的吗?如果是,您介意给我一个简单的优点/缺点列表,因为它似乎是一个相当复杂且“成熟的企业”领域。

有什么好处?与 RMI+Queue 相比性能如何? JMS 能打败 RMI+Queue 吗?

PS:我知道有 类似的问题,但我希望将 JMS 与 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 compared to RMI+Queue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

命比纸薄 2024-09-20 17:43:38

'自动重试
如果您是对服务器执行 RMI 的客户端,并且由于某种原因 RMI 失败,您必须自己重试。如果您使用 JMS 并且您是客户端,则只需发送 JMS 消息。当无法连接到服务器时,您的消息将被存储,并在服务器再次启动时传送。 ’

我认为答案具有误导性。从某种意义上说,它是有弹性的,发送到没有消费者的目的地的消息将被存储,直到有该消息的消费者或该消息过期。这假设 JMS 代理是可行的。

如果您尝试向无法访问的代理发送消息,那么您应该得到一个 JMSException,从这个意义上说,您的客户端消息可能会丢失,除非您的应用程序做出一些附带条件来存储它们本身并重试。从这个意义上说,JMS 服务器的客户端的行为与 RMI 服务器的客户端的行为相同。如果该服务器关闭,您仍然会丢失该消息。

'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.

银河中√捞星星 2024-09-20 17:43:37

简化的比较是(不是特定于 JMS,更像是一般情况下与 MQ 的比较)...

  1. 自动重试
    如果您是对服务器执行 RMI 的客户端,并且由于某种原因 RMI 失败,您必须自己重试。如果您使用 JMS 并且您是客户端,则只需发送 JMS 消息。当无法连接到服务器时,您的消息将被存储,并在服务器再次启动时传送。

  2. 持久队列
    由于您使用的是 LinkedBlockingQueue,因此您可以在内存中拥有有界队列或无界队列。前者一旦队列满了就会开始捕获线程,最终会在高负载下失败。后者最终会抛出 OutOfMemoryError 。如果您使用 JMS,它可以自动开始将消息“持久化”到“持久存储”。通常“持久存储”是数据库,它的容量通常比内存队列大得多。当然,当服务器宕机等情况时,内存队列的内容会丢失,而在 JMS 中,您可以选择在此类事件中幸存下来的持久消息/持久消息。这也让你可以拥有集群,这对于企业程序来说也是非常重要的...

  3. Abstraction
    您将使用标准化 API(好吧,RMI 中也有协议,但如果您想要传递消息,MQ 提供比 RMI+内存队列更高级别的抽象)。这意味着,您可以使用 JMS 的未来实现。也许不需要数据库来提供持久性和持久性,比今天的实现更具可扩展性等。或者您可以将相同的消息发送到完全不同的服务,因为标准化。基本上,更高的抽象可以为您提供灵活性,而 RMI+内存队列则不能。

不久前,我与一家大公司合作,希望使用他们的内部框架来集成我们的东西。那时我们还没有使用 MQ。我们要求他们使用我们自己的基于 RMI 的异步协议。相信我,我们对这个决定非常非常后悔......

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...

梦一生花开无言 2024-09-20 17:43:37

其他答案涵盖了JMS的许多方面,但我觉得一个非常重要的方面需要更多强调,即JMS以事务方式支持多个并发消费者这一事实。这对我来说是杀手级功能

  1. 您可以轻松构建一个具有非事务性单个消费者和生产者的系统。
  2. 您还可以通过更多的工作使其(或多或少)事务性
  3. 同样,您可以相对轻松地添加对多个生产者和单个消费者的支持,例如,如果您使用事务数据库来存储消息。
  4. 但是拥有多个并发消费者并让消息消费成为事务性的就变得非常困难。这基本上需要一个不平凡的锁定方案,即使使用事务数据库,任务也不容易。

然而,当我们谈论 JMS 可扩展性时,我们谈论的是:应用程序的能力。服务器添加/删除消费者/生产者来管理负载。

JMS 的其他优点是服务质量和管理,例如重新传递尝试、死消息队列、监控等。

如果您确实不需要这些,那么更简单的解决方案可能会起作用。您还可以看到我的另一个答案,其中我涵盖了类似的问题: 为什么选择 JMS 进行异步解决方案?

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 ?

思念绕指尖 2024-09-20 17:43:37

您的解决方案的“队列”部分使用什么?你自己的代码?

JMS 只是某些供应商的排队系统之上的一个 API,但它包含了远程处理方面。因此,从客户端的角度来看,您只需将消息放入队列(或主题,如果您正在执行发布订阅),然后忘记它。基础设施将其传递给听众。

我认为 JMS 的大部分功能来自于队列基础设施的实现质量,而不是 API 本身,这非常简单。

简单的 RMI 不能很好地扩展或处理可靠性问题,一个好的排队系统可以同时具有可扩展性和弹性。

我认为可以公平地说,JMS 和 Java EE 的其余部分旨在让您的应用程序达到企业质量。最初,我认为 Java EE 整体上很复杂,但我认为 JMS 是比较简单的部分之一。今天,我不确定编写 RMI + 您自己的队列是否比仅使用 JMS 更容易。

可能一个显着的区别是,使用 JMS 几乎假设您拥有一些基础设施,例如应用程序服务器。

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.

抚你发端 2024-09-20 17:43:37

JMS 是事务性的,可以与数据库事务协调。
JMS 将生产者和消费者解耦,这意味着它们不需要同时运行。
JMS 保证传递,这意味着在发生故障时消息可以保证到达那里(根据故障类型可能需要集群)。
JMS 可以进行同步、异步点对点以及发布/订阅。
大多数 JMS 实现都使用可以与其他语言、操作系统配合使用的排队系统。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文