在 AppEngine 标准环境中使用 java 创建线程

Creating Threads with java in AppEngine Standard Environment

我是 Google 云平台的新手。我正在使用 AppEngine 标准环境。我需要在 java 中创建 Threads 但我认为这是不可能的,是吗?

情况如下:

我需要为用户创建 Feed

存在三个名称为 d1, d2, d3 的数据库。

每当用户发送订阅源请求时 Java 创建三个线程,每个数据库一个。例如,d1 为 t1,d2 为 t2,d3 为 t3。这些线程必须 运行 异步以获得更好的性能,然后来自这 3 个线程的数据被组合并在响应中发送回用户。

我知道如何为此编写代码,但如您所知,我需要线程来完成这项工作。如果 AppEngine 标准 Env.不允许,那我该怎么办?还有别的办法吗?

他们在 GCP 文档中说:

To avoid using threads, consider Task Queues

我了解了任务队列。有两种类型的队列:推送和拉取。 运行 都是异步的,但它们不会向用户发回响应。我认为它们只是为了在后台完成任务而设计的。

你能告诉我怎样才能实现我的目标吗?为此我需要学习哪些东西?

注意:答案完全基于文档,我不是 java 用户。

标准环境支持线程,但有限制。来自 Threads:

Caution: Threads are a powerful feature that are full of surprises. To learn more about using threads with Java, we recommend Goetz, Java Concurrency in Practice.

A Java application can create a new thread, but there are some restrictions on how to do it. These threads can't "outlive" the request that creates them.

An application can

  • Implement java.lang.Runnable.
  • Create a thread factory by calling com.google.appengine.api.ThreadManager.currentRequestThreadFactory().
  • Call the factory's newRequestThread method, passing in the Runnable, newRequestThread(runnable), or use the factory object returned by com.google.appengine.api.ThreadManager.currentRequestThreadFactory() with an ExecutorService (e.g., call Executors.newCachedThreadPool(factory)).

However, you must use one of the methods on ThreadManager to create your threads. You cannot invoke new Thread() yourself or use the default thread factory.

An application can perform operations against the current thread, such as thread.interrupt().

Each request is limited to 50 concurrent request threads. The Java runtime will throw a java.lang.IllegalStateException if you try to create more than 50 threads in a single request.

When using threads, use high level concurrency objects, such as Executor and Runnable. Those take care of many of the subtle but important details of concurrency like Interrupts and scheduling and bookkeeping.

实现所需内容的一种优雅方式是在应用程序中创建可参数化端点

/runFeed?db=d1

从您的 "main" 应用程序代码中,您可以从 URLFetchService 执行 fetchAsync 调用,这将 return 您 java.util.concurrent.Future<HTTPResponse>

这将使您能够更好地监控应用程序的功能。 这将增加您的应用程序的网络延迟并增加其成本,因为 urlFetchService 不是免费的。