通过引用传递 JMS 消息有效内容的原因及时间
发送大型对象消息或字节消息时,序列化、反序列化和复制消息有效内容的内存和处理器使用成本可能会很高。 如果对连接工厂或激活规范启用通过引用传递消息有效内容属性,请通知缺省消息传递提供程序覆盖 JMS 1.1 规范并可能要减少或绕过此数据复制。
后台
JMS 1.1 规范声明对象消息是通过值传递的。这意味着 ObjectMessage 中的对象设置到消息有效内容中时,JMS 提供程序(例如 WebSphere® Application Server 中的缺省消息传递提供程序)必须获取该对象的副本,以防客户机应用程序在设置该对象后修改该对象。实际上这意味着对对象进行序列化,原因是没有其他完全可靠的方式来获取副本。该规范还声明当使用者应用程序从消息中获取数据时,JMS 提供程序必须创建并返回该数据的副本。
如果启用“通过引用传递消息有效内容”属性,那么可能会获取 JMS 消息传递的内存和性能改进。
- 这些属性绕过的 JMS 规范部分被定义用来确保消息数据完整性。
- 任何使用这些属性的 JMS 应用程序必须严格遵循本节稍后详细描述的规则,否则存在破坏数据完整性的风险。
- 启用这些属性之前,应阅读并了解此整个主题。
- producerDoesNotModifyPayloadAfterSet(对于连接工厂)或 forwarderDoesNotModifyPayloadAfterSet(对于激活规范)
- 启用此属性后,连接工厂产生的或通过激活规范转发的对象或字节消息设置到消息中时不会被复制,绝对需要时才会序列化。数据设置到消息中后,发送这类消息的应用程序就不能修改数据。
- consumerDoesNotModifyPayloadAfterGet
- 启用此属性后,通过连接工厂或激活规范接收的对象消息在绝对需要时才会序列化。应用程序不能修改从这些消息获取的数据。
通过引用传递消息有效内容的潜在好处
- JMS 应用程序符合本主题下一部分中描述的规则。
- 消息生产者和使用者应用程序在同一 JVM(服务器)及主管这些应用程序使用的目标的消息传递引擎中运行。
- 如果应用程序在不同服务器中运行,或者在 z/OS® 平台(其中 WebSphere Application Server 在多个 JVM 中运行)上运行,那么对象消息将序列化,并且无法针对这些消息获得任何性能优势。但仍可获得字节消息优势。
- 有许多内部运行时条件可能会导致消息序列化,所以即使配置符合本主题中描述的所有条件,您仍可能无法通过启用“通过引用传递消息有效内容”属性来获得任何性能优势。
潜在性能优势等级 | 配置和运行时事件 | 何时复制数据 |
---|---|---|
无潜在优势 | 未启用“通过引用传递消息有效内容”属性(缺省行为)。 |
将对象消息数据设置到消息中时以及从消息中检索对象消息数据时,复制对象消息数据。 将字节消息数据设置到消息中时以及从消息中检索字节消息数据时,复制字节消息数据。 |
一些潜在优势 | 已启用“通过引用传递消息有效内容”属性,并且符合下列其中一个或两个条件:
|
仅当必要时才复制字节消息数据。 |
最大潜在优势 | 已启用“通过引用传递消息有效内容”属性,并且符合下列两个条件:
|
仅当必要时才复制字节消息数据。 |
JMS 应用程序必须遵循的规则
“通过引用传递消息有效内容”属性绕过的 JMS 规范部分被定义用来确保消息数据完整性。如果 JMS 应用程序遵循下表中给出的规则,那么可安全地对应用程序使用的连接工厂和激活规范启用“通过引用传递消息有效内容”属性。
如果对不遵循这些规则的 JMS 应用程序启用“通过引用传递消息有效内容”属性,那么这些应用程序可能会接收到异常或者(更重要的是)消息数据的完整性被破坏。
应用程序类型 | 规则 |
---|---|
JMS 生产者应用程序 | 将对象设置到消息的有效内容中以后,发送对象消息的 JMS 生产者应用程序不能改变该对象。 发送字节消息的 JMS 生产者应用程序:
|
JMS 使用者应用程序 | 接收对象消息的 JMS 使用者应用程序不能改变它从消息中获取的有效内容。 |
JMS 转发者应用程序 注: JMS 转发器应用程序接收消息(通过连接工厂,或者如果该应用程序是消息驱动的 Bean,那么通过激活规范),然后将消息对象发送至另一目标。
|
将已接收消息的有效内容替换为新有效内容的 JMS 转发者应用程序:
|
确保对象消息可序列化
在正常 JMS 消息传递条件(即,未启用“通过引用传递消息有效内容”属性时)下,对象传递至消息传递系统时(例如,在 set 或 send 上),对象消息中的数据会序列化。如果消息有效内容不能序列化,那么会立即向客户机应用程序返回异常消息。
启用“通过引用传递消息有效内容”属性后,系统会接受来自客户机应用程序的消息有效内容而不会尝试使其序列化。如果系统以后发现该数据不能序列化,那么系统不会再通知发送该消息的客户机应用程序,并且因为该数据不可序列化,所以该系统不能保存或传送完整消息。消息及其属性会存储下来,但消息中的用户数据(有效内容)不能存储并且会被废弃。如果系统尝试将对象消息转换为调解的数据图时存在序列化问题,那么消息有效内容会被废弃,并且调解会接收数据值设置为空的消息。
如果数据不能序列化,那么数据会丢失。因此,应先在未启用“通过引用传递消息有效内容”属性的情况下测试配置,以检查发送到系统中的所有数据是否可序列化。
- CWSIK0200E: 类“{0}”的对象已设置到消息有效内容中,但它不能序列化。
- 解释:发送了对其连接工厂启用了 producerDoesNotModifyPayloadAfterSet 标志的对象消息,系统不能序列化此消息的有效内容。此消息数据已丢失。
- 操作:对连接工厂禁用 producerDoesNotModifyPayloadAfterSet。在未启用该标志的情况下,将对象设置到消息中的 JMS 应用程序将立即接收到所有序列化异常。
- JMS_IBM_ExceptionReason
- SIRCConstants.SIRC0200_OBJECT_FAILED_TO_SERIALIZE
- JMS_IBM_ExceptionTimestamp
- 对象序列化失败的时间(采用 System.currentTimeMillis() 格式)。
- JMS_IBM_ExceptionMessage
- 消息 CWSIK0200E(如先前所述)。
- SI_ExceptionReason
- SIRC0200_OBJECT_FAILED_TO_SERIALIZE
- SI_ExceptionTimestamp
- 对象序列化失败的时间(采用 System.currentTimeMillis() 格式)。
- SI_ExceptionInserts
- 包含一个条目的字符串数组。该条目包含对象的类名。