跳到主要内容

管理会话

会话是一个单线程上下文,通过它可以创建生产者和消费者。JMS 应用程序可以为每个连接创建一个或多个会话。Solace JMS API 支持事务性和非事务性会话。

有关使用 XA 会话的信息,请参阅使用 XA 事务。

创建会话

要创建会话,请调用 connection.createSession(boolean transacted, int acknowledgeMode)

其中:

transacted 表示会话是否为事务性。本地事务性会话可以将一组消息发送和一组消息接收组合成一个原子工作单元。默认情况下,此值设置为 false,会话不是事务性的。(有关事务性会话的更多信息,请参阅使用事务性会话。)

acknowledgeMode 是要使用的消息确认模式。有关更多信息,请参阅下面的确认模式。

对于事务性会话,确认模式被忽略,因为只有在调用事务的 commit() 时,事务中的消息才会被确认。

确认模式

对于非事务性会话,支持四种确认选项:

  • Session.AUTO_ACKNOWLEDGE 会话在从接收调用成功返回时自动确认客户端对消息的接收,或者在会话调用的消息监听器成功处理消息后返回时自动确认。

  • Session.DUPS_OK_ACKNOWLEDGE 会话可以通过将消息作为窗口组集体确认来惰性地确认每条消息的传递。此确认选项可以减少会话为确保不重复传递消息所需执行的工作量,但如果发生系统故障,也可能导致重复消息的传递。

  • Session.CLIENT_ACKNOWLEDGE 客户端通过显式调用 acknowledge() 方法来确认已消费的消息。这将自动确认会话传递的所有已传递消息。

一个会话可以持有多个 JMS 消费者。因此,当使用 CLIENT_ACKNOWLEDGE 时,一个消费者可能会确认另一个消费者的消息。如果两个消费者处理消息的时间不同,则可能会发生这种情况。在这种情况下,确认可能不会按接收顺序返回。

  • com.solacesystems.jms.SupportedProperty.SOL_CLIENT_ACKNOWLEDGE 这是 Solace 定义的消息确认模式。当一个会话上有多个消费者时,此选项允许每个消费者仅确认其接收的消息——一个消费者不能确认另一个消费者接收的消息。使用此模式时,每次调用 Message.acknowledge() 仅确认消费者接收到的消息。

会话及其消息生产者和消费者一次只能被一个线程访问。如果多个线程同时访问它们,则其行为是未定义的。

配置连接超时和重试

以下属性用于配置客户端的 JNDI 和 JMS 连接及重新连接行为。

当使用高可用性(HA)冗余事件代理对时,从一个事件代理故障转移到其配对代理通常会在 30 秒内发生,然而,应用程序应至少尝试重新连接五分钟。为了允许 HA 冗余事件代理的五分钟重新连接持续时间,请设置以下会话属性值:

  • 连接重试次数 — 1
  • 重新连接重试次数 — 20
  • 重新连接重试等待时间 — 3000 毫秒
  • 每个主机的连接重试次数 — 5

连接重试

连接重试属性指定在首次连接失败后尝试建立连接的最大次数。

有效范围是大于或等于 –1 的整数。值为 –1 表示允许无限次连接重试;值为 0 表示不允许自动连接重试(即,尝试一次后放弃)。

如果使用主机列表,每次连接重试将根据连接重试属性设置的值遍历主机列表。例如,如果使用值为 2 的连接重试,则 API 可能会依次尝试对主机列表中的每个条目建立 JNDI 连接。如果不成功,第二次连接重试将从第一个主机条目开始,并依次尝试每个主机条目。如果没有成功,则不再尝试进一步的连接重试。在遍历该列表时,对每个条目进行连接尝试的次数由每个主机的连接重试属性决定(参阅每个主机的连接重试)。

可以通过 JNDI 连接的连接重试属性设置连接重试值。有关更多信息,请参阅 JNDI 连接属性。

连接超时

连接超时属性指定建立初始连接允许的最大时间(以毫秒为单位)。

当使用主机列表时,为连接超时属性设置的时间将应用于对每个主机的每次连接尝试。例如,如果有四个主机条目,则应用程序可能需要等待每个主机条目的连接超时发生——乘以连接尝试次数——然后才能收到已建立连接或连接失败的通知。此等待时间还会因每次尝试连接到主机后发生的重新连接重试等待时间而延长。

如果套接字层检测到故障,连接尝试可能会更快终止。

可以通过 JNDI 或数据连接的连接超时属性设置连接超时值。有关更多信息,请参阅 JMS 属性参考。

重新连接重试

重新连接重试属性指定在断开连接后尝试重新连接到主机的次数。如果使用主机列表,此属性设置 API 将遍历主机列表以尝试重新连接到列表中的一个主机的次数。

有效范围是大于或等于 –1 的整数。值为 –1 表示允许无限次重新连接重试;值为 0 表示不允许自动重新连接重试(即,尝试一次后放弃)。

当使用主机列表时,如果 API 无法连接到列表中的第一个事件代理(即,首选事件代理),API 将尝试连接到下一个列出的事件代理,依此类推。API 将尝试连接到每个主机的次数由每个主机的连接重试属性设置的次数决定。

每次不成功的连接尝试后,API 将等待由重新连接重试等待属性设置的时间,然后尝试连接到同一个主机、下一个列出的主机,或者在所有列出的主机都尝试过之后,再次尝试连接到列表中的第一个主机。

当使用启用了事件代理冗余的主机时(即,列出的主机 IP 地址由一对冗余事件代理使用),应指定多个重新连接。禁用重新连接重试可能会影响在使用主/主冗余时可能发生的活动切换,并可能导致服务中断。例如,在故障转移场景中,如果没有启用重新连接重试,则无法尝试连接到冗余事件代理。

自动重新连接频率限制用于防止客户端在十秒内重新连接超过四次。如果事件代理允许在身份验证期间替换重复的客户端连接,则当使用具有相同客户端用户名的多个客户端时,它们可能会进入一个循环,其中一个客户端连接,而另一个客户端连接时则被断开。如果这些客户端具有非零的重新连接重试值,则每次一个断开连接的客户端成功重新连接时,它将断开另一个已连接的客户端。自动重新连接频率限制确保这种客户端连接/重新连接循环不会无限期地发生。

有关如何在身份验证期间启用重复客户端连接的替换,请参阅配置重复客户端的连接行为。

可以通过 JNDI 或数据连接的重新连接重试属性设置重新连接重试值。有关更多信息,请参阅 JMS 属性参考。

重新连接重试等待

重新连接重试等待属性设置在尝试重新连接到客户端连接的同一个主机的不成功尝试之后要等待的时间(以毫秒为单位)。此时间过后,可以进行另一次重新连接尝试。有效值为 1 或更大。

如果 API 遍历主机列表中的所有条目而未建立连接,并且允许连接重试,因为连接重试属性大于 0,则 API 将等待重新连接重试等待属性设置的时间,然后尝试连接到主机列表中的第一个主机。

可以通过 JNDI 或数据连接的重新连接重试等待属性设置重新连接重试等待值。有关更多信息,请参阅 JMS 属性参考。

每个主机的连接重试

当使用主机列表时,每个主机的连接重试属性设置在移动到列表中的下一个主机之前尝试连接或重新连接到一个主机的次数。在遍历列表时,每个条目将尝试连接重试属性设置的次数 + 1。

值为 0 表示不尝试单次连接或重新连接尝试。值为 –1 表示尝试无限次连接或重新连接重试(在这种情况下,API 仅尝试连接或重新连接到列出的第一个主机)。

如果对主机的连接或重新连接尝试不成功,API 必须等待重新连接重试等待属性设置的时间,然后才能进行另一次连接或重新连接尝试。

如果客户端应用程序断开连接,API 将尝试重新连接到它连接的事件代理,并且如果失败,它将尝试重新连接到下一个列出的主机,依此类推。如果应用程序在重新连接到新主机之前已发布保证消息,则新主机将没有所需的保证消息发布者状态,以与 API 就最后接收/确认的消息达成一致。因此,API 将重置发布者流状态,重新编号并重新发送任何未确认的消息。注意,如果新主机被配置为原始主机的复制配对,则重新发送消息可能会创建重复项,因为原始消息可能已成功传递给配对,尽管从 API 的角度来看它们未被确认。在这种情况下,由接收应用程序以适当的方式解决此重复问题。

注意,对于 7.1.2 之前的 API 版本,如果在发布保证消息后重新连接到不同的主机,API 将关闭新创建的会话并引发会话事件——应用程序负责重新连接并重新发送任何未确认的已发布消息。要使用此传统行为,必须将保证消息传递重新连接失败操作属性更改为适当的非默认值。有关更多信息,请参阅 JMS 属性参考。

可以通过 JNDI 或数据连接的每个主机的连接重试属性设置每个主机的连接重试值。有关更多信息,请参阅 JMS 属性参考。

处理JMS连接事件

Solace JMS 实现为 JMS 连接事件(例如,SolReconnectedEventSolReconnectingEvent)提供了一个回调监听器(SolConnectionEventListener)。

要使您的 JMS 应用程序在 SolConnection 事件发生时接收异步通知,您必须实现 SolConnectionEventListener 接口并注册到 SolConnectionEventSource

事件通知可以在连接的 I/O 和事件线程上发生。

关闭会话

要关闭会话,请调用 Session.closeSession()

调用此方法时,将在同一会话中创建的生产者和消费者将被关闭。也就是说,在调用 Session.closeSession() 之前,无需显式关闭它们。

Session.closeSession() 调用将阻塞,直到正在进行的接收调用或消息监听器完成。当关闭此会话时,阻塞的消息消费者接收调用将返回 null

关闭事务性会话将回滚任何正在进行的事务。

此方法是会话接口中唯一可以并发调用的方法。

如果提供者已为会话在 JVM 外部分配了资源,则应在调用 Session.closeSession() 之前关闭这些资源,因为依赖于垃圾收集来及时回收这些资源可能不够及时。