在App Engine中的多个实例上可用的布尔标志

时间:2011-06-11 22:59:02

标签: java google-app-engine

我有一个运行在多个实例上的应用程序,所有请求都来自一个servlet。

我需要运行一个cron作业,每周执行一次约3分钟。在那个cron调用期间,某些标志/布尔值将在某处被修改,以便servlet可以拾取并发送“服务器暂时不可用”类型的消息,而不是处理请求。一旦cron作业完成,它就会将其标记为true。

我不能使用单例或静态布尔值,因为应用程序将在多个实例中。我也不希望servlet在每次请求时都必须从数据存储区中获取值,因为这将意味着数十万个额外的数据存储区读取。

我该怎么办?有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我认为你可以在memcached中存储boolean。 GAE有一个Memcached的Cache API。但请注意,缓存值不是持久的,甚至可能无法存活3分钟。我认为你应该有一个坚定的时间在你的一个Java类或.properties文件中硬编码cron任务,然后当你的任务完成时,它应该查看硬编码的时间并根据下一轮安排自己那时。

通过这种方式,您的servlet也可以查看该时间,并且不会在您要指定的时间间隔内处理请求。是的,这将非常快,但您的工作将定期安排到固定时间,除非您重新部署应用程序,否则您将无法更改此工作。

我认为更好的解决方案是你应该在数据存储区中保留布尔值并使用缓存。请参阅以下算法:

is my boolean in the cache?
yes: 
    [alright, then choose to serve or not to serve request using it.]
no: 
    [fetch variable from datastore and put it on the cache.] (cache miss)

同样,缓存速度很快,但不如程序中的时间表硬编码那么多。

编辑:另一种解决方案。 (但无法实施)

如果要在任务执行期间提供页面,则应使用任务api

首先,您应该熟悉使用倒计时来完成任务(在本例中是下周)http://code.google.com/appengine/docs/java/javadoc/com/google/appengine/api/taskqueue/TaskOptions.html#countdownMillis(long

然后你可以使用Queuesize()方法 - 我期待它在那里,但显然谷歌没有实现它 - 看看任务队列大小是否为0,那么它意味着它现在正在处理,因为当任务完成时,它会在1周后再次提交。

答案 1 :(得分:0)

一种方法是让cron作业向所有servlet实例正在监听的JMS主题发布消息。消息可以通知servlet实例将你提到的静态布尔值设置为true或false。