我需要一些关于Azure应用程序的建筑建议。所以,有一个包含项目的队列,假设它是[A,B,A,B,D]。
队列中的每个不同项目都将获得一个随机类别,并且可以在队列中多次使用相同的项目。类别分配由一些工作者角色完成,这些角色执行以下操作:如果项目已经分配了类别,则会将项目添加到类别,否则它将创建新类别并添加项目。所以它就像:
D: has category? no. Create category 123. Assign [D, 123]
B: has category? no. Create category 435. Assign [B, 435]
A: has category? no. Create category 154. Assign [A, 154]
B: has category? yes. Assign [B, 435] (category already created)
... etc ...
我的dillema是:我如何同步工人,以便同一项目不会得到两个类别?如果两个工人选择项目B,那么“B”可以有两个类别。
答案 0 :(得分:2)
确保不会出现重复项的唯一方法是锁定分配可从两个实例访问的类别。在Azure中最常用的方法是在存储中使用blob。如果您的项目类型为Foo,并且您正在通过队列传递Foo的Id,则伪代码将如下所示:
int fooId = GetIdFromQueue();
Foo myFoo = LoadFooFromStorage(fooId);
if (myFoo.Category == null)
{
CreateLockBlobIfNoExistForFoo(fooId);
while (not GetLockOnBlobForFoo(fooId))
{
WaitForSomeTime();
}
// Need to reload the underlying item as another thread may have
// been assigning the category while we were waiting on the lock
Foo myFoo = LoadFooFromStorage(fooId);
if (myFoo.Category == null)
{
myFoo.Category = GetRandomCategory();
SaveFoo(myFoo);
}
ReleaseLease(fooId);
}
你需要查看blob租约的一些细节,但希望这足以让你开始。
答案 1 :(得分:1)
将您的项目/类别列表保存在您的工作人员角色可以访问的azure表中,但是如果没有某种限制,这仍然可能会重复。例如,对于限制,在一个具有合理等待(1-3秒)的定时器循环中设置GetMessage() - 并且在每次调用GetMessage()之前,调用PeekMessages(5)来查看但不会使接下来的5个消息出列。循环遍历它们并为任何未分配的项目分配类别,并在调用GetMessage()之前将它们存储在Azure表中。