以下代码在GAE中是合法的。但似乎从未正确运行(日志行) 当我使用
ExecutorService executor = Executors.newFixedThreadPool(factory);
它将获得 java.lang.IllegalStateException:每个请求不能超过50个活动线程。 所以我把它限制在10个。
ThreadFactory factory = ThreadManager.currentRequestThreadFactory();
ExecutorService executor = Executors.newFixedThreadPool(10,factory);
executor.execute(ThreadManager.createThreadForCurrentRequest(new Runnable() {
@Override
public void run() {
log.severe(" can run here.... " );
Movie m = insertMovie(pm, id);//But cannot enter this method!!
}
}));
很好。谁能告诉我原因。以及如何在GAE中运行multiThreading。
答案 0 :(得分:0)
我使用cron xml进行网络刮刀,但在GAE中需要10分钟。所以我想用线程来做。但我不知道如何在GAE中使用线程
一个线程,如果它在自动调整的模块上运行(例如默认模块通常是),就无济于事 - 它会在超时发生时被终止,并且超时会 是10分钟。
相反,简单的解决方案是使用适当的模块 - 请参阅https://cloud.google.com/appengine/docs/java/modules/。表"缩放类型"清楚地显示:自动缩放模块中允许后台线程不,但在手动缩放和基本缩放模块中允许 。因此,对于需要运行时间超过自动模块允许的截止时间的工作,请使用手动或基本模块。
对于OP表达的要求,单实例Basic模块(具有较小的,因此更便宜的实例类,因为抓取不是CPU和内存密集型)可能恰到好处,即在web.xml中和appengine-web.xml配置文件(通常在Java中使用),可能类似于
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>your-app-here</application>
<module>scraper</module>
<version>one</version>
<threadsafe>true</threadsafe>
<instance-class>B2</instance-class>
<basic-scaling>
<max-instances>1</max-instances>
<idle-timeout>10m</idle-timeout>
</basic-scaling>
</appengine-web-app>
除了可能需要的任何其他模块之外(通常,例如,自动缩放default
模块以提供用户流量。)
转换GAE应用程序(默认使用名为default
的单个自动缩放模块)以使用多个模块还需要其他步骤 - https://cloud.google.com/appengine/docs/java/modules/处的文档非常详细,并且此外,您可以在https://cloud.google.com/appengine/docs/java/modules/converting获取有关如何迁移现有GAE应用以使用模块的具体说明。
一旦你迁移了,你就可以在你的基本扩展模块中使用线程,虽然这可能不需要,因为获得了关键目标(删除完成的10分钟截止日期),线程与否,只需通过基本缩放模块上运行的代码。
另一种架构是使用Task Queue - 在这种情况下,任务处理程序(如果在自动缩放模块上运行)仍然有10分钟的截止日期;但是,在截止日期前不久,App Engine会引发一个DeadlineExceededException,您的代码可以捕获该代码以保存已完成的任何工作,并将另一个任务排队以从第一个停止的位置继续。然而,虽然这是一个非常可靠的架构,但这可能需要对您的抓取任务进行更多的返工,而不是简单地取消截止日期,使用我上面推荐的基本缩放模块。