【发布时间】:2012-04-16 11:08:10
【问题描述】:
有没有办法通过 GAE 上的任务队列确保 FIFO(先进先出)行为?
GAE 文档说 FIFO 是影响任务执行顺序的因素之一,但同一份文档说“系统的调度可能会‘跳’新任务到队列的头部”,我已经确认了这种行为测试。效果:我的事件被乱序处理了。
文档说:
https://developers.google.com/appengine/docs/java/taskqueue/overview-push
任务执行的顺序取决于几个因素:
任务在队列中的位置。 App Engine 尝试根据 FIFO >(先进先出)顺序处理任务。通常,任务被插入到队列的末尾,并且 从队列的头部执行。
队列中的任务积压。系统尝试提供最低延迟 通过对调度程序的特别优化的通知,任何给定的任务都是可能的。 因此,如果队列有大量任务积压, 系统的调度可能会将新任务“跳转”到队列的头部。
任务的 etaMillis 属性的值。此属性指定 任务可以执行的最早时间。 App Engine 总是等到 在指定的 ETA 之后处理推送任务。
任务的 countdownMillis 属性的值。此属性指定最小值 执行任务前等待的秒数。倒计时和 eta 是互斥的;如果您指定一个,请不要指定另一个。
我需要做什么?在我的用例中,我每天将处理来自车辆的 1-2 百万个事件。这些事件可以以任何间隔(1 秒、1 分钟或 1 小时)发送。必须确保事件处理的顺序。 我需要按时间戳顺序进行处理,它是在车内的嵌入式设备上生成的。
我现在有什么?
由消费者调用并创建任务的 Rest servlet(事件数据在有效负载上)。
-
在这之后,一个worker servlet得到这个Task并且:
反序列化事件数据;
将事件放在数据存储上;
在数据存储上更新车辆。
那么,再一次,有什么方法可以保证 FIFO 的行为?或者我该如何改进这个解决方案来获得这个?
【问题讨论】:
-
为什么需要严格的 FIFO?请记住,在分布式系统中,事件的顺序有点模糊 - 当您的前端和后端分布在多台机器上时,即使告诉几个几乎同时发生的请求中的哪一个最先发生也是困难的(而且通常毫无意义)。作为最终结果,您要达到什么目标?
-
我们跟踪公共巴士,所以我们需要知道它什么时候停在一个公共汽车站,什么时候开始旅行,或者什么时候超过了速度限制。问题是一些事件与之前的事件相关,因为我们也做状态管理。例如:如果公共汽车在之前的事件中记录了“关闭的行程”,则只能“开启行程”。所以,你可以想象如果我把这些事件弄乱了会发生什么......
-
任务队列在任何情况下听起来都不是最好的方法。您要做的是使用数据存储事务,并将给定总线的状态转换集限制为状态机允许的状态转换。
-
在没有任务队列的维护或应用更新的情况下,如何停止接收事件?
-
我不明白你在问什么。您通常如何接收活动更新?
标签: java google-app-engine task-queue