无法 运行 使用 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 创建的“请求上下文”中执行。这不是用户请求,但仍然是防止实例在线程进程中间卸载的请求。
我有一个网络应用程序,人们可以在其中上传 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 创建的“请求上下文”中执行。这不是用户请求,但仍然是防止实例在线程进程中间卸载的请求。