服务器群集:一项任务

时间:2012-11-23 16:50:23

标签: cron cluster-computing

背景

我们的客户使用他们设定每日预算的服务。这是一项预付费服务,我们每天都会从用户预算中分配一笔特定金额。

表:

  • 预算 - 我们每天可以支付的费用
  • 资金 - 客户真实余额
  • money_allocated - 从今天可以支出的资金中扣除的金额(基于预算

每隔几分钟就会运行一个cron作业并检查:

  • 如果用户在某一天 money_allocated
  • 如果 money_allocated > = 预算(用户可能会在当天增加预算)

在第一种情况下,我们分配全额每日预算,后者 - 预算与当天已分配金额之间的差异(在这种情况下,我们在 money_allocated 中为此创建额外记录天)。

分配有两个阶段 - 在第一轮中我们添加一行状态为“待定”(请求分配),另一个cron检查所有“待定”分配并将资金从转移到 money_allocated 如果用户有足够的钱。这会将状态更改为“已完成”。

问题

我们有一组应用程序服务器(在NLB下),并且在每个应用程序上运行cron作业,这意味着可能会意外地多次分配资金(或者如果我们实施错误的“已分配”触发器,则根本不分配资金)。

我们的选择包括:

  • 仅在一台服务器上运行cron作业 - 没有冗余,客户投诉和因失败而丢失的资金
  • money_allocated 上添加一个类似于(client_id,date,amount)的唯一索引 - 如果客户将预算加倍或者将预算增加多倍,则不会在给定日期分配更多资金白天的金额

可以选择在预算中记录每个动作,并将所有分配链接到“当天的第一次分配”或“预算更改(ID xxx)”(将此添加到唯一索引)以及)。然而,这看起来不够性感。

还有其他选择吗?任何建议都将受到高度赞赏!

1 个答案:

答案 0 :(得分:2)

好的,所以我最终在群集的一个实例上运行了这个。如果您使用Amazon AWS并且处于类似情况,则以下是其中一个选项..

在每台计算机上,在您的cron作业代码的开头,执行以下操作:

  • 调用describe_load_balancers(AWS API),解析响应以获取所有实例的列表/数组
  • 获取http://169.254.169.254/latest/meta-data/instance-id - 这将返回正在发送请求的计算机的实例ID
  • 如果收到的实例ID在所有实例的列表/数组中为#1 - 如果不是,请继续 - 退出

此外,请务必在describe_load_balancers返回健康和不健康实例的列表时,在短时间内自动替换此负载均衡器下的不健康实例。如果实例#1发生故障,你可能会在一段时间内完成一项工作。