SenderApp 正在将值发送到服务总线队列,在另一端我们有两个接收器实例。
要求是我们只将已更改的值保存到数据库(所有传入的值首先保存到发生比较的redis缓存中)。
SenderApp 按以下顺序发送三个值到队列:(1, 2, 1)。
-----1---2---1------------------------>
现在,这些值使用 FIFO 方法进入队列,在队列的另一端,我们有两个接收器应用程序实例。
这就是它变得有趣的地方。
假设由于延迟或其他一些因素,第二个接收器实例处理值(2)的速度很慢,并最终将其保存到所有三个值中的最后一个数据库中。
所以它应该是这样的:
接收器实例#1
--------------------1---1------------------------>
接收器实例#2
--------------------------------------2-------->
现在我们遇到了问题。实例一将第二个发送的值(1)与第一个值(也是 1)进行比较,并且它不会保存到数据库中。发送到服务总线队列的值带有附加的时间戳。
它还需要是具有相当可扩展性的解决方案。
欢迎所有想法,也许利用 redis 缓存,也许服务总线 session ?
编辑:
更多说明:
每条传入消息都附加有设备 ID 和值,因此我们不能为该特定设备保存任何连续的重复值。
例如,我们有来自同一设备的两条传入消息。
第一条传入消息的值为 1,设备 ID 为 999(我们必须保存它)。
但现在下一条传入消息的值也为 1,设备 ID 为 999。
所以这将是连续的重复,我们不能保存它。
另外,使这个问题变得困难的是我们也无法直接在发送方保存值。
最佳答案
竞争的消费者(接收者)将违背按消息发送顺序处理消息的要求。为了坚持按顺序处理,Azure 服务总线 message sessions功能可以提供帮助。单个接收者在任何时候只处理一个 session ;多个接收器不进行处理。这消除了来自同一源的消息被并行且无序处理的可能性。这仍然是一种可扩展的方法,因为接收者可以处理不同的 session 。如果给定 session 的消息在一段时间后到达, session 处理将由任何竞争接收者进行。
在这种情况下,当唯一可识别的设备发出消息时,设备 ID 可以用作 session ID。
值得注意的是,每个接收器可以并行处理多个 session ,而不仅仅是单个 session 。这样,解决方案就可以横向扩展和纵向扩展,具体取决于所使用的计算和每条消息执行的代码的复杂性。
关于c# - 维护多个实例的处理顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73342496/