跳到主要内容

在PubSub+ JCSMP API中创建消息

当发布消息时,客户端应用程序会显式创建消息,而 PubSub+ JCSMP API 会在匹配消息传递时隐式创建消息。PubSub+ JCSMP API 创建一个指定类的对象来封装消息。

在创建消息时,应考虑以下因素:

  • 消息所有权
  • 消息类型
  • 重置消息
  • 设置消息属性

消息所有权

当为发布创建消息时,存在两种消息所有权模型:

  • 会话无关

在会话无关的消息所有权模型中,客户端应用程序可以在发送操作之间重复使用消息。消息按需分配,并且当客户端应用程序完成消息处理后,会显式地释放这些消息。

  • 会话相关

JCSMP 还支持会话相关消息所有权模型。在此模型中,消息实例预先分配到生产者消息池中;客户端应用程序可以从消息池中“获取”一个消息实例,填充它,并发送它。当发送操作返回时,API 会自动重置消息实例,并将其“放回”消息池。这是通过会话上的 Producer 接口完成的。会话相关消息不能用于批量发送。

会话相关消息所有权模型主要用于与使用 JCSMP 的现有应用程序保持向后兼容。建议新的 Java 应用程序使用会话无关消息。如果消息被预先分配并尽可能重复使用,使用会话无关消息所有权模型不会带来性能损失。

要创建会话无关消息,请使用 JCSMPFactory.createMessage(...)。此方法创建一个指定类的对象来封装消息。

有关如何创建会话无关消息的示例,请参阅 Solace 开发者中心中的 ADPubAck 示例。

要创建会话相关消息,请使用以下方法:

  • producer.createBytesXMLMessage()
  • producer.createBytesMessage()
  • producer.createMapMessage()
  • producer.createStreamMessage()
  • producer.createTextMessage()
  • producer.createXMLContentMessage()

消息类型

PubSub+ 消息传递 API 支持由消息负载定义的不同消息类型。为了方便程序员,PubSub+ JCSMP API 提供了以下类型安全的消息类型/类。

消息类描述
BytesXMLMessage一个非结构化类,可用于发送包含 XML 数据负载的消息。
BytesMessage一个结构化类,可用于发送包含二进制附件中的未解释字节流的消息。
MapMessage一个结构化类,可用于发送包含结构化数据类型(SDT)映射的消息。请参阅在 PubSub+ JCSMP API 中使用结构化数据。
StreamMessage一个结构化类,可用于发送包含 SDT 流的消息。请参阅在 PubSub+ JCSMP API 中使用结构化数据。
TextMessage一个结构化类,可用于发送包含文本的消息。
XMLContentMessage一个结构化类,可用于发送包含 XML 数据的消息。

JCSMP 消息类

重置消息

在会话无关消息所有权模型中重复使用消息时,您可以释放与消息缓冲区相关的所有内存,以便将消息缓冲区重置为其原始状态(即,就像它刚刚被分配一样)。所有字段都被重置为其默认值。

要重置消息,请使用 XMLMessage.reset()

设置消息属性

可以为保证消息设置一些重要的消息属性,这些属性将影响消息在发布时的路由方式。

要查看可以设置的消息属性的完整列表,请参阅适用于相应消息传递 API 的 PubSub+ 消息传递 API 文档。

立即确认

如果此属性设置为 false(默认值),则事件代理应在达到发布窗口大小的三分之一或经过一秒钟时,为在发布窗口中收到的消息发送确认。这些是在事件代理上不可配置的阈值。

  • 此属性对传出的直接消息或客户端接收到的消息没有影响。
  • 此属性可能在传递给接收客户端之前被接收事件代理移除。因此,接收客户端不应依赖此属性存在。

要设置事件代理是否应立即确认已发布消息,请使用 Message.setAckImmediately(...)

服务等级

COS 级别 2 是 Solace 的保留值;目前,COS 级别为 2 的消息被视为低优先级。

您必须使用每个 API 提供的数据结构设置 COS 值。不要直接使用整数设置值。

有关如何配置队列或主题端点以选择性地丢弃低优先级消息的信息,请参阅 Guaranteed Messaging Configuration 中的 reject-low-priority-msgreject-low-priority-msg-limit 队列 CONFIG 和主题端点 CONFIG 命令。

要设置 COS 标志,请使用 Message.setCos(...)

相关性ID

可以为消息设置一个唯一的相关性 ID(以字符串形式)。相关性 ID 可用于关联请求消息及其对应的回复。相关性 ID 也可以用作消息选择器中的标识符。

有关 Guaranteed 消息的请求回复消息传递的信息,请参阅 PubSub+ JCSMP API 中的请求回复消息传递。有关选择器的信息,请参阅在 PubSub+ JCSMP API 中使用选择器。

要设置相关性 ID,请使用 Message.setCorrelationID(...)

死信队列资格

超过其 TTL 或最大重新投递次数的保证消息可以从持久队列或主题端点移动到死信队列(DMQ),而不是被丢弃,如果这些消息被标记为 DMQ 合格。DMQ 只是一个被分配为另一个持久端点的 DMQ 的持久队列。有关详细信息,请参阅配置死信队列。

DMQ 资格作为消息标志设置。值为 true 表示发布的消息有资格进入 DMQ。

为直接消息设置 DMQ 资格仅在消息的主题与端点上的主题订阅匹配且事件代理将收到的消息的传递模式更改为非持久时才有效。有关如何根据主题匹配修改收到的消息的传递模式的详细信息,请参阅保证消息。

要启用消息的 DMQ 资格,请使用 Message.setDMQEligible(...)

有关如何使消息成为 DMQ 合格的示例,请参阅 Solace 开发者中心中的 messageTTLAndDeadMessageQueue 示例。

仅传递给一个订阅者

在发布时可以为保证消息设置仅传递给一个属性。

仅传递给一个标志仅影响具有直接传递模式的消息的投递。因此,当为持久或非持久消息启用仅传递给一个标志时,除非该消息的传递模式在匹配分配给队列或主题端点目的地的主题订阅时更改为直接,否则它不会影响消息投递行为。在这种情况下,传递模式更改为直接的消息将只传递给一个直接消息消费者,而不是所有消费者,即使可能有多个具有适当订阅的客户端能够接收该消息。

要设置仅传递给一个消息标志,请使用 XMLMessage.setDeliverToOne(...)

传递模式

每个发布的消息都有一个传递模式。默认情况下,使用直接传递。要使用保证消息传递,在大多数情况下,将传递模式设置为持久。

保证消息传递还支持非持久传递模式;但是,此模式仅适用于 JMS 消息传递应用程序。

有关详细信息,请参阅 PubSub+ JCSMP API 中的消息传递模式。

要设置传递模式,请使用 Message.setDeliveryMode(...)

有关如何为消息设置传递模式的示例,请参阅 Solace 开发者中心中的 DirectPubSub 示例。

目的地

发布的保证消息根据其设置的队列或主题目的地进行路由。目的地在用于发布消息的发送方法上设置。请参阅一次发送一条消息或一次性发送多条消息。

相关示例

有关如何向主题发布消息的示例,请参阅 Solace 开发者中心中的 DirectPubSub 示例。

有关如何向队列发布消息的示例,请参阅 Solace 开发者中心中的 QueueProvisionAndBrowse 示例。

消息省略资格

事件代理的消息省略功能使客户端能够仅以它们能够管理的速率接收它们订阅的主题上发布的最新直接消息。在需要较慢的消息速率或存在慢速消费者(即,未能足够快速消费消息的客户端)的情况下,使用消息省略可能会很有用。

要使用消息省略,需要执行以下操作:

  • 发布的消息必须标记为有资格进行消息省略。
  • 接收客户端应用程序必须通过其客户端用户名分配一个允许其使用消息省略的客户端配置文件。客户端配置文件还设置了一个速率,以控制延迟间隔,即新的省略合格消息省略之前排队等待向客户端投递的先前版本。有关如何配置客户端配置文件并将其分配给客户端的详细信息,请参阅配置客户端身份验证。

消息省略标志仅影响具有直接传递模式的消息的投递。因此,当为持久或非持久消息启用消息省略标志时,除非该消息的传递模式在匹配客户端主题订阅时更改为直接,否则它不会影响消息投递行为。在这种情况下,传递模式更改为直接的消息然后可以被省略。

要启用消息的省略资格,请使用 Message.setElidingEligible(...)

消息过期

可以为发送的消息设置一个过期时间(以毫秒为单位),从 1970 年 1 月 1 日午夜 UTC 开始计算。默认情况下,已发布消息的过期值为 0,这意味着消息永远不会过期。

仅当客户端显式设置大于 0 的过期值,并且 TTL 未设置或设置为 0 时,消息过期字段才会从端到端通过事件代理传输。

要设置消息过期,请使用 Message.setExpiration(...)

为了保持准确的消息过期值,同步连接到事件代理的客户端的系统时钟非常重要。

消息 TTL 是消息传递网络中防止过期消息传递给客户端的唯一机制。设置过期值对消息在网络中的生命周期没有影响。也就是说,即使已过期的消息仍然会传递给消费者。如果需要对收到的过期消息采取进一步措施(例如丢弃消息),则由接收应用程序负责执行该操作。

启用消息过期计算

要计算同时考虑消息 TTL 值的消息过期值,请为会话启用消息过期计算。默认情况下,为了提高系统性能,不启用消息过期计算。

当启用消息过期计算且消息的 TTL 值大于 0 时,API 会在消息发送或接收后,使用消息 TTL 和 UTC 值的总和更新消息的过期值。

对于具有直接传递模式的消息,仅当事件代理自动将消息的传递模式从直接更改为非持久,因为消息的主题与分配给端点的主题订阅匹配时,设置 TTL 和过期值才有效。有关如何根据主题匹配修改消息传递模式的详细信息,请参阅主题匹配和消息传递模式。

要启用消息过期计算,请使用 JCSMPProperties.CALCULATE_MESSAGE_EXPIRATION 属性。

有关如何设置过期时间或启用消息过期计算的示例,请参阅 Solace 开发者中心中的 messageTTLAndDeadMessageQueue 示例。

消息优先级

可以将消息优先级值应用于发布到事件代理的消息。当队列或主题端点配置为尊重消息优先级时,事件代理使用此值按适当顺序投递消息。也就是说,高优先级的消息会在低优先级的消息之前发送。有效值范围为 0(最低优先级)到 255(最高优先级),但事件代理将所有高于 9 的值视为优先级 9。默认值为 4。

当端点配置为强制执行消息优先级时,它增加了在从连接故障中恢复后,向消费客户端投递重复消息的可能性。

要设置消息优先级,请使用 Message.setPriority(...)

分区键

您可以在消息中设置分区键,以利用分区队列。分区队列允许您轻松扩展事件网格中的消费者应用程序数量,同时保持具有相同分区键的所有已发布消息的消息顺序。PubSub+ 事件代理确保所有相关事件以正确的顺序传递给同一个消费者,并且在您添加或移除消费者时重新平衡事件流。有关详细信息,请参阅分区队列。

您可以通过在表中指定用户消息属性来在 API 中设置分区键。此值存储在消息的 JMSXGroupID 字段中,并在网络跳转之间保持不变。

要配置 PubSub+ 消息属性中的键以使用分区队列,请使用 putString(key,value) 函数在消息上设置键值对,其中:

  • key — 常量 XMLMessage.MessageUserPropertyConstants.QUEUE_PARTITION_KEY 或字符串值 JMSXGroupID
  • value — 表示分区键值的字符串。客户端应用程序在发布时设置该值。

以下示例将分区键 value 设置为 Group-0

TextMessage message = JCSMPFactory.onlyInstance().createMessage(TextMessage.class);
SDTMap messageProperties = JCSMPFactory.onlyInstance().createMap();
messageProperties.putString(XMLMessage.MessageUserPropertyConstants.QUEUE_PARTITION_KEY,"Group-0");
message.setProperties(messageProperties);

回复到目的地

当消息作为请求发布时,可以设置回复到目的地,以指示请求消息的回复应发送到何处。有关 Guaranteed 消息的请求回复消息传递的信息,请参阅 PubSub+ JCSMP API 中的请求回复消息传递。

要设置回复到目的地,请使用 Message.setReplyTo(...)

有关如何创建包含回复到目的地的保证请求消息的示例,请参阅 Solace 开发者中心中的 RRGuaranteedRequesterRRGuaranteedReplier 示例。

生存时间

为了确保不会将旧消息传递给消费客户端,可以为每个要发布的保证消息设置一个生存时间(TTL,以毫秒为单位)。当队列或主题端点配置为尊重消息 TTL 时,如果收到的消息的 TTL 已过期,则可以将其丢弃,或者如果消息符合死信队列(DMQ)的条件,则将其移动到事件代理上配置的 DMQ。

默认情况下,已发布消息的 TTL 值为 0,这意味着消息永远不会过期。

有关如何配置端点以尊重消息 TTL 的信息,请参阅在 PubSub+ JCSMP API 中定义端点属性或适用于所用消息传递 API 的 PubSub+ 消息传递 API 文档。有关使消息符合 DMQ 条件的信息,请参阅死信队列资格。

要设置消息的生存时间值,请使用 Message.setTimeToLive(...)

有关如何为已发布消息设置 TTL 的示例,请参阅 Solace 开发者中心中的 messageTTLAndDeadMessageQueue 示例。