您需要传递令牌。以下是它的工作原理:
首先,创建第二个队列并将一条消息放入其中。现在用以下逻辑启动每个程序。
- 使用无限或长等待间隔和
FAIL_IF_QUIESCING 选项从同步点下的令牌队列中取出令牌消息。
- 将令牌消息放回同一 UOW 中的令牌队列中。
- 从同一 UOW 下的应用程序队列中获取下一条消息。
- 正常处理应用程序的消息。
- 提交 UOW。
您可以使用任意数量的应用实例。您将在每个应用程序实例的两个队列中的每一个上看到一个输入句柄。没有应用程序实例必须处理由于独占使用队列而导致的错误。
由于只有一个令牌消息并且一次只有一个应用程序可以将其保存在同步点下,因此只有一个应用程序可以主动处理应用程序消息。由于应用程序队列外的GET 依赖于令牌队列外成功的GET,因此所有应用程序消息都按严格的顺序处理。
注意:应用程序将使用与令牌队列中的令牌消息一样多的并发线程来处理应用程序消息。如果有人将另一个令牌消息添加到令牌队列,则会丢失严格的序列处理。因此,不得将对该队列的读/写访问权限授予应用服务帐户以外的任何人。此外,通常会构造该令牌消息,以便应用程序可以识别它。如果一个杂散的无关消息到达那里,应用程序应该忽略它并发出警告。
您会看到两个应用程序之间的消息分布相当均匀。如果您使用两个以上的应用程序,您可能会看到非常un的分布,因为队列句柄是在堆栈中管理的。当一个实例提交其 UOW 时,下一个实例的句柄位于堆栈的顶部,因此它会获取下一条消息。在处理该消息时,刚刚提交的实例会将其GET 放置在堆栈顶部。如果您有 3 个或更多侦听实例,则只有前两个实例会看到任何流量。
这可确保每次处理队列外的消息。它确实不保证您不会被骗。
如果您在同步点下执行所有操作,则不会丢失任何消息。但是,有一种情况是消息被检索和处理,然后COMMIT 调用失败。在这种情况下,事务被回滚,并且相同的消息再次变得可用。如果您使用的是 1 阶段提交而不是 XA,则不会回滚该消息的处理。
好消息是令牌消息也将处于同步点之下,这解决了孤立客户端通道需要一段时间才能释放事务的问题。新连接将获得比孤儿事务在同步点下保存的消息更早的消息。最终,通道代理超时将消息释放回队列,但实际上将其位置更改为在它被隔离时处理的任何消息之后。
在这种情况下,令牌消息也被隔离,因此在这种类型的连接丢失消息处理后会暂时停止并等待通道代理超时。如果发生这种情况,只需在具有 UOW 的实例上发出 STOP CHANNEL 命令。
根据特定于该答案的其他问题详细信息进行更新
持有此令牌的队列必须是某个队列管理器的一部分。
现在,如果我们有故障转移,该控制队列将不再是
无障碍。这有点意味着我们需要另一个控制队列
为故障转移做好准备。
令牌队列与应用程序队列一样可用或不可用。只需要一个。如果应用程序需要 HA,则应使用多实例 QMgr 或硬件 HA 集群。这些共享磁盘,因此故障转移中出现的 QMgr 与应用程序连接到的 QMgr 相同,只是在不同的物理位置。
如果应用需要 DR,可以将 QMgr 的日志和数据目录下的磁盘复制到 DR 站点。但是,在主数据中心进行处理时,不应监听这些实例。
监听器实例应该知道故障转移已经启动,所以
它可以在正常操作期间停止侦听控制队列,并且
切换到二级。我无法使用侦听器执行此操作
单独实例。
为什么不呢? WMQ 拥有可重新连接的客户端已经很长时间了,v7.0.1 中的多实例功能使重新连接变得非常简单。作为管理员,您的工作是确保不超过一个应用程序实例和令牌(不是触发器!)队列可用。在中断期间,客户端无需任何应用程序代码即可进入重试状态。它会找到任何一个启动并连接的实例。
将消息放入队列的实际生产者必须
通知监听器实例停止监听正常操作
控制队列并切换到辅助队列。
问题是关于并发消费者的序列化。这是一种设计,生产者和消费者必须在一个共同的地点会合。恰好与此重叠的不同问题仅在于它因序列化而有些复杂。如果您需要探索拓扑,请提出不同的问题。
这个令牌系统不是真的
反应对吗?它更多的是周期性的东西。所以假设我们没有得到
几个小时内的任何消息。听众仍将不断
检查队列,因为令牌消息不断触发一个实例
一个接一个。
这不使用触发。它使用令牌(不是触发器!)消息,就像文件系统或数据库使用锁一样,以促进序列化。无论哪个侦听器获取令牌消息,都会在应用程序队列上无限等待。其他侦听器在令牌(不是触发器!)队列上有无限等待。基本上,他们闲置直到消息到达。零重新连接、零轮询、零 CPU 周期。如果您需要知道它们是否还活着,请偶尔让它们在应用程序队列中超时。这会在令牌队列上回滚它们的 UOW,从而将令牌传递给另一个侦听器。
第三个确实是插入令牌消息的问题。
在首次安装或故障恢复期间,我们将获得额外的
手动插入此令牌的手动步骤(因为令牌将是
有时会在故障转移中丢失)。
为什么?您是否经常遇到 MQ 在同步点下丢失持久性消息?如果是这样,你做错了。 ;-) 在具有严格序列化要求的情况下,队列只能有一个活动实例。如果由于某种原因,除了通过磁盘复制之外,还有其他预定义的应用程序队列实例,那么将有一个令牌实例(不是触发器!)队列也在其旁边预定义,并且每个令牌(不是触发器!)消息等待队列。面对严格的消息顺序要求,肯定没有人会这样做,但如果他们这样做,这些队列肯定会在不使用时被禁用。
我们不能真正成为听众之一
实例会这样做,因为如果侦听器实例找不到消息
这有点意味着其他一些侦听器实例具有令牌。
正确。侦听器可以检查队列深度、事务、输入句柄等,但通常明智的做法是避免将应用程序逻辑与控制逻辑混合。
所以
这个逻辑必须分开。如果我们真的把一些有意义的
信息到这个令牌消息中,它必须是一个实用程序,必须是
触发而不是通过 UI 插入。
为什么?您的编码人员处理应用消息中的结构化数据,对吗?如果这被认为要困难得多,那么有人做错了。 ;-) 将格式化令牌(不是触发器!)消息的实例写入队列,然后将其卸载到文件中。当需要重新初始化队列时,使用Q或QLoad先清空队列,再将文件加载进去。 那个实用程序是在执行其魔法之前打开队列以供独占使用、检查深度、检查句柄等的工具。当我为咨询客户执行此操作时,我通常会定义一个在 MQ 启动时初始化队列的服务并且还在应用程序 GUI 中为操作和支持人员提供一个功能。只要管理令牌(而不是触发器)队列的应用程序在这些操作期间获得它以进行独占访问,它实际上是如何完成的或控制应用程序有多少实例并不重要。
通常,我还使用消息中的结构向侦听器发送命令。有真正的令牌消息,然后有命令应用程序实例做事的消息。例如,拥有非事务性“ping”功能真的很棒。如果我在单个 UOW 中的令牌(不是触发器!)队列上放置的 ping 消息比我有应用程序实例监听的多,我保证会联系所有这些。通过这种方式,我可以检测到僵尸。根据需要多少检测,侦听器可以通过在日志、控制台、事件队列等中提供状态(正常运行时间、处理的消息等)来对 ping 做出反应。
我想第一个和第三个并不是真正的问题,只是额外的
如果我们使用轮询器,则不需要开销
实施。
这很好,因为这都是非常标准的东西。问题主要在于序列化的要求与 HA/DR 的要求相冲突。您正在寻找的是跨多个物理位置实现单个逻辑队列的全局事务原子性。 IBM MQ 从未尝试过提供这一点,尽管 WAS Messaging Engine 提供了。最接近的 MQ 是使用两个具有内存到内存复制消息和事务数据的 MQ 设备,但这在光速延迟开始显着影响吞吐量之前只有几英里。它无法满足您的 DR 需求。事实上,如果您想在 DR 数据中心实现零恢复点,没有什么可以做到这一点。