Google App Engine原本是不支持后台任务的,毕竟人家是免费开放资源,不可能让大家随意使用CPU。同时也有每个http请求最高执行时间10秒的限制,因此必须借助外部服务器才能实现某些长期运行的后台运算任务。不过最近俺又看了看Google App Engine的网站,发现前一阵子上线的Cron Jobs功能,再搭配最新公测的Task Queue 已经可以完美的实现后台任务的功能了。
我们假设一个简单的在线RSS Reader,它需要后台定期的取很多feed的更新,如果我们使用自己服务器的环境,多半会写一个程序,遍历一遍所有的Feed去抓取更新,然后把这个程序配置为cron任务在服务器上定期执行,当然要是Feed比较多,就一个程序一直不停的在后台运行也可以。
但是在GAE的环境下就不行了,因为GAE有每次请求10秒的执行时间限制,所以即使在推出Cron Jobs的功能后,还是不能很容易的实现我们上面说的功能,因为遍历一次所有的feed并取数据肯定要超过10秒钟。一个可能的方法是只能处理很小的任务(肯定不超时),就把所有的执行状态都存在memcache中,然后等下次job的时候继续上次的位置处理。
最近上线的Task Queue功能可以改变这种状态,还是通过Corn Jobs定期执行任务,这个任务只是把“遍历一遍所有Feed”这种大任务拆分成许多可以在10秒中内完成的小任务,比如取一个feed的更新做一个任务,通过Task Queue api添加到Queue(如果你要做实验,默认的队列就可以),只添加不执行因此不会超时,之后Queue会逐渐的消费这些任务 - 这样就完成了原定的后台任务。
其实有意思的是前后两个后台运行方案的比较。我们第一印象的方案和最终用GAE实现的方案的最大不同就是可伸缩性(Scalability)。比如系统要求所有的Feed都要15分钟内更新一次,而Feed的数量大到一定的规模后,遍历获取所有Feed的更新要超过15分钟,那么肯定需要修改程序进行多进程处理。如果是固定的多进程数那么Feed的规模再变大还是有问题,如果是随Feed量控制进程数,又要设计每个进程的Feed分配问题,总而言之肯定不容易。而GAE的版的方案则完全没有这个问题,随着Feed的增加,我们只要不断加强Queue的消费能力就可以了(对应GAE就是bill更多的quota),也就是有一个明确的有效的可扩展点。
这其实是GAE的特征,说到底它是靠可伸缩性赚钱的 - 人们编写的程序在负荷小的时候可以免费运行,等到负荷上去了,不用修改程序,只要给GAE钱买更多的资源不需要大改才程序。如果做不到这样的可伸缩性,也就没人愿意在GAE上付费,GAE也就没有生命力,商业云计算都是以可伸缩性为商业模式的基础吧。其实我是想说,上面的例子给我的提示就是,评估一个软件架构的扩展性的时候,可以想想这个方案能否用GAE实现,无论最后应用是否用GAE来做,能用GAE实现的方案一定有很强的可伸缩性,不能用GAE实现的方案可能可伸缩性会差一些。
