google appengine/python: 我可以依赖任务队列的重试机制来减少插入次数吗?
假设我的应用有一个页面,用户可以在上面添加评论。每当添加一条评论时,就会有一个任务队列的工作者被添加进去。所以如果添加了100条评论,就会有100次任务队列的插入。
(注意:上面的例子只是为了说明我的问题)
假设我想确保插入的次数保持在最低限度(这样我就不会遇到1万次插入的限制)。
我可以这样做:
a) 每当添加一条评论时,调用taskqueue.add(name="stickytask", url="/blah") - 由于这是一个命名的任务队列,如果已经存在同名的任务队列,它就不会被重新插入。
b) /blah这个工作者的URL会读取新添加的评论,处理第一条评论,然后如果还有更多评论需要处理,就返回一个不是200的状态码 - 这样可以确保任务会被重试,下次尝试时会处理下一条评论,依此类推。
这样,所有100条评论就只用1次或几次任务队列的插入就能处理完。(注意:如果在一段时间内没有新评论添加,所有评论都处理完了,那么下一条添加的评论就会导致新的任务队列插入。)
不过根据文档(见下面的片段),它提到“系统会逐渐减缓”。这是否意味着每次返回“非200”的HTTP状态码时,下一次重试会有延迟?
文档中提到:如果某个任务的执行失败(返回任何非200 OK的HTTP状态码),App Engine会尝试重试,直到成功。系统会逐渐减缓,以免给你的应用带来太多请求,但至少会每天重试失败的任务一次。
1 个回答
没有必要假装出现错误(然后还要处理重试等问题)——这是一种不靠谱且脆弱的做法。如果你担心每次新评论都安排一个任务会超过任务队列目前的严格限制,那就把还没有处理的评论先“批量”存储起来(可能还可以放在缓存里,这样会更快,但这不是必须的),然后在那个时候就不要安排任何任务。
相反,可以设置一个定时任务(比如每分钟执行一次),它可以处理一些评论或者安排适量的任务来处理待处理的评论——因为你只从一个定时任务中安排任务,所以很容易确保你每天安排的任务不会超过10,000个。
不要让任务队列让你忘记了定时任务的存在:一个好的“批处理”处理架构通常会同时使用定时任务和排队任务,以简化整体设计。
为了在一次请求中最大化完成有用的工作(无论是来自排队任务还是定时任务),可以考虑基于监控你的CPU使用情况——当CPU成为限制你每次请求能完成的工作的因素时,这可以帮助你在一次请求中尽可能多地完成小的可调度工作单元。我认为这种方法比等待超出配额错误、捕获它并迅速关闭要更稳妥,因为那可能会导致一些你无法控制的后果。