gpt4 book ai didi

c# - 服务的多个实例 - 如何保证一个对象只被处理一次?

转载 作者:行者123 更新时间:2023-12-03 05:09:47 28 4
gpt4 key购买 nike

我有以下设置:部署了 N 个 Azure 辅助角色实例。我们的桌面应用程序将一条消息上传到Azure,然后上传一组与该消息相关的图像。 Message 知道它需要什么图像。

这两个事件(消息上传和图像上传)是独立的 - 图像可以在用户生成消息之前上传(称为缓存 - 但它更复杂),或者在消息之后几秒/分钟上传消息已上传到 Azure。

我将消息存储在 Azure MSSQL 数据库中,图像存储在 blob 中,它们的 URL 存储在数据库中。还有 MessageToImage 表,用于存储消息图像的链接。这是一个简化的数据库结构(请原谅我的 C#):

class Message
{
public int Id;
public string Text;
}

class Image
{
public int Id;
public string Name;
public string BlobUrl; // Null if image was not received by the service yet
}

class MessageToImage
{
public int MessageId;
public List<int> ImageIds;
}

当我们收到包含所有图像的消息(即所有图像均已上传)时,我们需要对其执行其他操作(比方说,发布到 Facebook)。 问题如下:我如何保证该消息只会被处理一次?在最坏的情况下,我将有 N 个实例同时接收消息的 N 个图像 - 哪个实例将“选择”将消息发送到进一步处理?我如何保证它只会发生一次?

到目前为止,我提出了以下想法:

  1. 确保“更新图像的 BlobUrl”数据库逻辑是原子的,并将返回消息的“缺失”图像数量。这样,我将仅在一个实例上触发进一步处理 - 该实例收到“0”作为数据库更新的结果。但是:我怎样才能在 MSSQL 级别上做到这一点?更复杂 - 我如何使用 Entity Framework 做到这一点?

  2. 有一个专门的辅助角色,该角色将选择包含所有图像的消息 - 并将其发送以进行处理。但这不能很好地扩展......并且看起来有点难看。

还有其他想法/建议吗?

谢谢!

<小时/>

更新1@Richard 和@Rob 建议使用服务总线队列。我确实调查过。我仍然没有答案的部分是 WORKER ROLE 中决定何时将消息发送到队列进行处理的代码应该是什么样子?仅当所有图像都存在于数据库/blob 中(即上传到 Azure 云)时,消息才会发送到队列。在这里我仍然想指出我的极端情况示例 - 我有 10 个图像由 10 个工作角色同时处理。对于所有实例,处理同时结束。每个角色都会使用上传的图像 URL 更新数据库。然后我应该以某种方式触发最终的消息处理 - 这意味着其中一个实例应该获得优先级。我不清楚我应该如何做到这一点。

希望这能让我的问题更清晰一些。

最佳答案

创建 Azure 服务总线队列并让客户端应用将消息发布到队列。然后您的辅助角色就可以从队列中提取消息并处理这些消息。

服务总线队列的伟大之处在于它们保证消息只能从队列中取出一次,然后消息被标记为“已获取”。如果事务未在(可配置的)时间段内标记为完成,则消息将返回到队列,准备好由下一个工作请求拉取。

这意味着,如果您的辅助角色在处理过程中失败,该消息最终将重新出现在队列中,以便下一个辅助角色拾取它并(希望)完成所需的工作。

阅读此内容以获取更多信息:

How to use Service Bus Queues

关于c# - 服务的多个实例 - 如何保证一个对象只被处理一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16703298/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com