问题描述
我有一个运行多个实例的应用程序,所有请求都通过一个servlet来进行。
我需要执行一项cron作业,每周执行一次,持续约3分钟。在该cron调用期间,将在某处修改某种标记/布尔值,以便servlet可以接收并发送“服务器暂时不可用”类型的消息,而不用处理请求。 Cron作业完成后,将其标记为true。
我不能使用单例或静态布尔值,因为该应用程序将在多个实例中使用。我也不希望servlet每次请求都必须从数据存储中获取值,因为这将意味着成千上万的额外数据存储读取。
我能做什么?有任何想法吗?
解决方法
我认为您也许可以将布尔值存储在memcached中。 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(长)
然后,您可以使用Queue的size()
方法(我希望它在那里,但显然Google并未实现它)来查看任务队列大小是否为0,这意味着它现在就被处理了,因为当任务完成时,它将在1周后再次提交。
, 一种方法是让cron作业将消息发布到所有servlet实例正在侦听的JMS主题。这些消息可能会通知Servlet实例在您提到的静态布尔值中将值设置为true或false。