无法 运行 使用 GCP App 引擎中的 Thread 在 Flask 中进行后台作业

Unable to run background job in flask using Thread in GCP App engine

我有一个网络应用程序,人们可以在其中上传 CSV 文件(没有并发上传,每天仅上传 1 次),CSV 文件中大约有 1000 行。此行是根据少数条件在 firestore 数据库中处理和更新的,我们不希望 运行 并行提取这些行,因为可能存在并发问题。

每行处理大约需要 1 秒,因此作业需要 15 分钟。这必须异步完成。我们所有的应用程序都在 GCP APP Engine 中,我的 python 代码如下所示

app.py

@app.route('/batch', methods=['POST'])
def read_csv(**kwargs):
     threading.Thread(target=iterate_csv_file, args=(
        df, file_name, file_content)).start()

main.py

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5000, debug=True)

app.yaml

runtime: python37
entrypoint: gunicorn -t 120 -b :$PORT main:app
service: my-test
instance_class: F4
automatic_scaling:
  min_instances: 1
  max_instances: 1000

handlers:
  - url: /.*
    secure: always
    script: auto

7 分钟后出现以下错误(处理大约 400 行后)

Exception in thread Thread-58:
 textPayload: "Traceback (most recent call last):
  File "/layers/google.python.pip/pip/lib/python3.7/site-packages/firebase_admin/_user_mgt.py", line 837, in _make_request
    return self.http_client.body_and_response(method, url, **kwargs)
  File "/layers/google.python.pip/pip/lib/python3.7/site-packages/firebase_admin/_http_client.py", line 125, in body_and_response
    resp = self.request(method, url, **kwargs)
  File "/layers/google.python.pip/pip/lib/python3.7/site-packages/firebase_admin/_http_client.py", line 117, in request
    resp.raise_for_status()
  File "/layers/google.python.pip/pip/lib/python3.7/site-packages/requests/models.py", line 940, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://identitytoolkit.googleapis.com/v1/projects/my-project/accounts" 

现在看了很多celery和RabbitMQ的教程。对于我的用例,是否需要使用它们或简单的后台线程应该工作?为什么我在使用后台线程时会出错。此错误是否与烧瓶或 GCP 或某些超时有关。当这个后台线程在 GCP 中 运行ning 时,我正在浏览网站(会调用几个 API)。我遵循了以下教程并提出了这段代码 https://pastebin.com/vnypfpU7

您不能在 App Engine 标准中创建线程,运行时不是为此设计的。如果当前未处理任何请求,则可以随时卸载该实例。这是你的情况,因为不再有正在进行的请求,只是请求处理上下文之外的后台线程。

即使将最小实例设置为 1,也可以创建新实例并删除旧实例,“1”会受到尊重,因为您始终至少有 1 个实例来为流量提供服务。

为此,您需要创建一个 Cloud Task 来回调您的 App Engine。这一次,该过程在 Cloud Task 创建的“请求上下文”中执行。这不是用户请求,但仍然是防止实例在线程进程中间卸载的请求。