azure – 如何在水平扩展写入时避免并发问题?
假设有一个工作服务从队列接收消息,从文档数据库读取具有指定Id的产品,根据消息应用一些操作逻辑,最后将更新的产品写回数据库(a).
在处理不同的产品时,这项工作可以安全地并行完成,因此我们可以横向扩展(b).但是,如果多个服务实例在同一产品上运行,我们可能会遇到并发问题或数据库中的并发异常,在这种情况下我们应该应用一些重试逻辑(并且仍然可能再次失败,等等) . 问题:我们如何避免这种情况?有没有办法可以确保两个实例不能在同一产品上运行? 示例/使用案例:在线商店在productA,productB和productC上有很好的销售,一小时结束,数百名客户正在购买.对于每次购买,都会将消息排入队列(productId,numberOfItems,price).目标:我们如何运行我们的工作服务的三个实例,并确保productA的所有消息最终都在instanceA,productB到instanceB和productC到instanceC(导致没有并发问题)? 注意:我的服务是用C#编写的,作为工作者角色托管在Azure上,我使用Azure队列进行消息传递,我正在考虑使用Mongo进行存储.此外,实体ID是GUID. 它更多的是关于技术/设计,所以如果你使用不同的工具来解决问题,我仍然感兴趣. 解决方法
对于这种事情,我使用blob租约.基本上,我使用某个已知存储帐户中的实体ID创建一个blob.当worker 1选择实体时,它会尝试获取blob上的租约(如果它不存在,则创建blob本身).如果两者都成功,那么我允许处理消息.之后总是发布租约.
如果我没有成功,我将消息转发回队列 我遵循史蒂夫马克思最初在http://blog.smarx.com/posts/managing-concurrency-in-windows-azure-with-leases所描述的apporach,尽管已经调整使用新的存储库 评论后编辑: 例如:考虑CQRS设计模式并独立存储每个消息处理的变化.因此,产品实体现在是各种工作人员对实体所做的所有更改的集合,按顺序重新应用并重新水合成单个对象 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- bash – Jenkins文本参数 – 特殊字符乱码(不需要的变量替换
- 20个使用Bootstrap前端框架制作的漂亮网站
- AD属性修改 office 365 delivery management 设定
- angular – 无法读取null的属性’config’
- 为什么Scala说它看不到org.joda.time.Period的成员?
- Angular2中AfterContentChecked和AfterViewChecked有什么区
- shell学习二-----变量基本知识
- 具有嵌套状态的Angular2路由
- function – scala foreach和map initializers
- shell 设置超时时间