【发布时间】:2019-09-05 14:38:19
【问题描述】:
我有一个架构,其中有一组“守护程序”进程构成我的平台。这些守护进程是完整的 Hazelcast 成员,并且是应用程序中所有数据的数据存储。实际的业务逻辑与守护进程分离,并驻留在大量微服务风格的组件中,这些组件要么物理上位于同一台服务器上,要么位于不同的机器(虚拟机、容器等)上。服务可以修改数据存储中的数据并从守护进程订阅数据存储中的事件,但模型实际上完全不同,并且从 Hazelcast 的地图视图中抽象出来,所以我的事件不像监听地图修改那么简单,而是在多个地图时生成在某些方面进行了修改。服务客户端(Hazelcast lite 成员)定义他们想要收听的事件。问题是,每种服务组件的多个实例(任意数量)都可以运行,而我只希望一个实例(任意一个)来处理每个事件(即循环或负载平衡)。
我目前的解决方案是使用 Hazelcast 队列。守护进程监听地图上的事件并根据这些地图决定何时触发事件。作为密钥所有者的守护进程将触发事件,因此事件仅在一个地方触发。我将此事件推送到一个队列中,该事件的每个侦听器实例都连接到该队列。因此,无论谁先到该事件,都会对其进行处理。
例如,我有一个名为 IncomingBondPrices 的数据源微服务,它将价格放入守护程序数据存储区。我有 10 个名为 priceProcessor 的单独微服务实例。当价格达到某个阈值时,守护程序会触发一个事件(我们称之为“PriceThresholdReached”)。我希望 priceProcessor 的 10 个实例中的一个且只有一个来处理每个事件,因此,如果我以数百或数千个价格进行流式传输,则处理事件的负载将分散到我的 priceProcessor 实例中。
我担心的是如果没有消费者会发生什么?我找不到任何方法来计算 hazelcast 队列中的消费者数量。系统是完全动态的,服务启动并将他们感兴趣的事件定义发送给守护进程。有可能启动任何给定服务的 1、2、20 或 100 个实例,并且它们可能全部关闭并且将不再有该事件的任何订阅者。如果当前没有给定事件的订阅者,我想销毁队列而不向其推送任何事件。如果没有订阅者,我不希望事件排队......
我该如何管理这个?我能想出的唯一方法是在守护进程中为每种事件类型保留订阅者的数量,并在队列降至 0 时销毁队列。但我担心的是,如果没有正常关闭,服务很可能会被终止,所以它们将没有机会明确告诉守护程序他们不再在听了。管理这将需要我明确检查所有成员是否仍然活着,或者在 Hazlecast 发现成员已断开连接时订阅事件,然后跟踪所有成员是否订阅以结束它们。有一个更好的方法吗?它似乎过于复杂。理想情况下,我想要以某种方式在队列中查找在任何给定时间有多少当前成员在队列上运行 take(),如果该值为 0 并且队列上没有数据,则将其销毁。
谢谢你, 特洛伊。
【问题讨论】: