将 JMS 应用程序移植到 MQ
今天,如果我们使用 JMS API 构建一个应用程序(使用 MDB 作为消息侦听器,将其托管在 GlassFish 或 Weblogic 10 上),明天假设流量变得疯狂,我们是否可以在不更改代码的情况下将此应用程序移植到某些产品(例如 Websphere MQ) ...因为理论上 MQ 更像是一个专用的 JMS 提供者...
Today if we build an application using the JMS API (using MDBs as message listeners, host it on lets say GlassFish or Weblogic 10) and tomorrow lets say the traffic goes crazy, can we port this application without code changes to some product like Websphere MQ... coz theoretically MQ is more like a dedicated JMS provider ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,也不是。 (所有最佳问题的答案始终是“视情况而定”。)
如果应用程序遵守 JMS 规范,那么它应该在任何符合 JMS 的提供程序上运行,无需更改。这是个好消息。
坏消息是提供者如何实现 JMS 确实很重要。例如,JMS 1.1 规范的第 6.5 节对以下主题进行了如下说明:
这意味着规范的某些部分可以由 JMS 传输提供者解释。应用程序所有者将决定在移植应用程序时如何映射这些差异。
这个问题的另一个方面是,即使两个传输提供商严格遵循规范,API 背后的行为也可能不同。连接管理就是一个例子。一些提供程序将连接故障转移到客户端透明,另一些提供程序则要求客户端在失败后重新驱动连接序列。这两种方法都可以 100% JMS 兼容,但都需要不同的应用程序逻辑。
所以答案是,遵循 JMS API 让您非常接近完全可移植,并且所需的移植量取决于传输提供者如何解释规范部分和/或实现规范中不明确的功能的差异。
Yes and no. (The answer to all the best questions is always "it depends.")
If the application adheres to the JMS specification then it should run unchanged on any JMS compliant provider. That's the good news.
The bad news is that it really does matter how the provider implemented JMS. For example, Section 6.5 of the JMS 1.1 specification says this about topics:
What this means is that certain parts of the specification are open to interpretation of the JMS transport provider. It will be up to the application owner to determine how to map these differences when porting applications.
Another aspect of this question is that even when the specification is followed strictly by two transport providers, the behavior behind the API may differ. An example of this is connection management. Some providers fail connections over transparently to the client, others ask the client to re-drive the connection sequence after a failure. Both approaches can be 100% JMS compatible and yet both require different application logic.
So the answer is that adhering to the JMS API gets you very close to fully portable and the amount of porting that is required depends on the differences in how the transport provider interprets parts of the spec and/or implemented features that are ambiguous in the spec.
开发人员很容易(或有时被要求)在基于 JMS 的应用程序中使用供应商专有的功能。在我使用 JMS 的短时间内,我注意到开发人员可能诉诸使用专有 API 的四个原因。
首先,从命名服务获取
Destination
和ConnectionFactory
对象很不方便,特别是对于刚接触 JMS 的开发人员来说,他们不想在使用 JMS 之前花时间学习 JMS 管理命令。能够编写应用程序。使用供应商专有函数直接创建Destination
和ConnectionFactory
对象可能会更方便。其次,JMS 产品通常提供高于 JMS 规范中定义的服务质量。如果这些服务质量与
Session
、Producer
或Consumer
相关,那么供应商很自然地提供专有的对这些类型进行 >set()
操作。简而言之,并非所有专有服务质量都可以封装在管理对象中。第三,当与 JMS 相关的操作失败时,它会抛出
JMSException
(的子类型)。应用程序的开发人员可能希望根据异常的性质,通过多种方式之一来处理捕获的异常。然而,JMS 规范规定,JMSException
提供的三条信息中有两条是 JMS 供应商专有的。因此,开发人员在决定如何处理异常时可能需要依赖异常中包含的供应商专有信息。最后,JMS 指定消息由三部分组成:(1) 标头字段、(2) 任意属性(即 name=value 对)和 (3) 正文。 (2) 的预期用途是支持消费者应用程序中灵活的消息选择。例如,在伦敦等地运行的生产者应用程序可能会在发送消息之前将 location=London 添加到消息的属性中。然后,消费者应用程序可以使用消息选择器开头的属性名称供 JMS 供应商使用,并且某些供应商使用此类属性来基于每条消息指定专有的服务质量。希望使用专有的、按消息提供的服务质量的开发人员必须修改生产者应用程序的代码,以便在发送消息之前设置专有属性。
“(location = 'London')”
来确保它只接收具有该属性值的消息。听起来很好。不好的一点是,JMS 规范保留了以 JMS_T.Rob 关于主题层次结构的警告是另一个需要警惕的问题。
It is very easy for developers to feel tempted (or sometimes be required) to use vendor-proprietary functionality in a JMS-based application. In the short period of time I spent using JMS, I noticed four reasons why a developer might resort to using a proprietary API.
First, obtaining
Destination
andConnectionFactory
objects from a naming service is inconvenient, especially for a developer new to JMS who does not want to have to spend time learning JMS administration commands before being able to write an application. It might be more convenient to use vendor-proprietary functions to createDestination
andConnectionFactory
objects directly.Second, it is common for JMS products to offer qualities of service above and beyond those defined in the JMS specification. If these qualities of service are related to, say,
Session
,Producer
orConsumer
, then it is natural for a vendor to provide proprietaryset<Name>()
operations on those types. Put simply, not all proprietary qualities of service can be encapsulated in administered objects.Third, when a JMS-related operation fails, it throws a (subtype of)
JMSException
. The developer of an application might wish to process a caught exception in one of several ways, depending on the nature of the exception. However, the JMS specification states that two out of the three pieces of information provided byJMSException
are proprietary to a JMS vendor. Because of this, a developer may need to rely on vendor-proprietary information contained in an exception when deciding how to process it.Finally, JMS specifies that a message is composed of three parts: (1) header fields, (2) arbitrary properties (that is, name=value pairs), and (3) a body. The intended use of (2) is to support flexible message selection in consumer applications. For example, a producer application running in, say, London, might add location=London to a message’s properties before sending the message. A Consumer application could then use the message selector
"(location = 'London')"
to ensure it receives only messages with that property value. That sounds good. The bad bit is that the JMS specification reserves property names starting withJMS_<vendor>
for use by JMS vendors, and some vendors use such properties to specify a proprietary quality of service on a per message basis. A developer who wishes to make use of a proprietary, per-message quality of service will have to modify the code of a producer application so it sets the proprietary property prior to sending a message.T.Rob's warning about topic hierarchies is another issue to be wary about.
WebSphere MQ 是一个非常成熟、稳定的平台,据我所知,它完全符合 JMS 标准。许多组织使用基于 MQ 的 JMS 作为传输。我曾在几个同时使用 JMS 和本机 MQ 机制与 MQ 层对话的地方工作过,而且我还没有遇到过任何关于 IBM JMS 实现的抱怨。不过,我还没有与任何更改过 JMS 提供程序的人合作过...
IBM 提供了一堆仅引用 javax.jms 包的 Java 库,因此只要您没有在代码中添加任何特定于供应商的增强功能,您应该能够插入 MQ 库以使 MQ 成为您的 JMS 提供者。 (您可能需要使用 MQ 工具进行一些管理来执行设置 JMS 订阅之类的操作,但是...我没有使用 MQ 的 JMS 方面,仅使用了核心库。)
查看 此 IBM 页面 了解有关 MQ JMS 库的更多详细信息。
如果您只使用 WebSphere MQ 作为示例,那么是的,您可能仍然需要检查候选供应商是否符合规范,但 JMS 已经存在了一段时间,我认为所有大公司的产品都是合适的 JMS 提供商。
WebSphere MQ is a very mature, stable platform which - as far as I know - fully complies with the JMS standard. Numerous organisations use JMS over MQ as their transport. I have worked in several that use both JMS and native MQ mechanisms to talk to the MQ layer, and I have not come across any complaints about the IBM JMS implementation. I have not worked with anyone that has changed JMS providers, though...
IBM provides a bunch of Java libraries that only reference the javax.jms package, so as long as you haven't let any vendor-specific enhancements into your code, you should be able to slot in the MQ libraries to have MQ become your JMS provider. (You may need to do some administration with the MQ tooling to do things like set up JMS subscriptions, however... I haven't used the JMS aspects of MQ, only the core libraries.)
Check out this IBM page for some more details on the MQ JMS libraries.
If you only used WebSphere MQ as an example then yes, you may still need to check the candidate vendors' compliance with the spec, but JMS has been around a while and I think all of the big players' offerings would be a suitable JMS provider.
由于 JMS 是一个相对简单的 API(与 JDBC 等相比),因此它在实现之间仍然具有相当的可移植性,只要您 首先采取一些基本措施。
至于从 WebSphereMQ 获得更好的性能,我不确定您会发现情况确实如此。如果您使用的是点对点,也许可以。但如果你正在做 Pub/Sub,那就不太可能了。请参阅此基准,该基准无疑是由竞争对手,但它使用第三方基准,并且实际上对一些开源参赛者相当慷慨。
Since JMS is a relatively simple API (compared to JDBC etc.) it remains quite portable between implementations, provided you take some basic measures to begin with.
As far as getting better performance from WebSphereMQ, I am not sure you will find that to be the case. If you are using Point-to-Point, perhaps. But if you are doing Pub/Sub, it's pretty unlikely. See this benchmark which is admittedly published by a competitor, but it uses a third party benchmark and is actually quite generous to some open source contestants.