AppEng Py Flexi :: 长时间运行的请求 :: 502 错误
Posted
技术标签:
【中文标题】AppEng Py Flexi :: 长时间运行的请求 :: 502 错误【英文标题】:AppEng Py Flexi :: Long running request :: 502 error 【发布时间】:2018-08-14 02:20:48 【问题描述】:我的应用程序(py3,应用程序引擎 flexi)接收 Web 请求 > 运行 BQ 查询 > 获取数据 > 处理数据(不是很占用 CPU!) > 返回响应。
请求可以被调用
直接在浏览器中尝试网址 或通过 cron 作业调用 URL 作业由于 BQ 查询的性质:
我确定处理该请求需要 >30 秒(大约 2-5 分钟) 我不关心并发请求的数量,只有少数请求会同时进来 (我遇到了 [CRITICAL] WORKER TIMEOUT (pid:7) 错误,我相信通过调整 gunicorn.conf.py 中的 timeout 设置可以解决该错误。但是 nginx 继续返回 502 error
作为响应(并且 cron 作业状态以失败结束)
有人可以分享为什么我继续收到 502 错误以及我应该调整哪个参数(在 app.yaml 或我的应用程序 PY 代码中)来管理这个超时?以及如何处理您肯定需要 2-5 分钟(甚至更长时间!)的此类请求的最佳实践
另外,我正在考虑创建 Cloud Function 端点,因为 CF 支持 PY(并且支持 higher timeouts as high as 9 minutes..)
【问题讨论】:
【参考方案1】:即使您知道您的请求需要不到 9 分钟的时间,让客户端应用程序等待也不是一个好习惯,因为有多种方式可能会中断请求。
做到这一点的方法是通过作业/操作(就像BQ 和大多数 Google API 一样)。一旦开始查询(插入 BQ 作业),您就存储 BQ 返回的作业 ID 并为您的应用生成一个新 ID(例如在数据存储中)。
然后客户端应用程序开始轮询此操作。它每 5 秒询问您的应用程序(或您的函数)是否已完成操作。然后,您的应用程序会从存储中检索 BQ 作业 ID checks in the BQ API if that job is finished,并返回未完成状态以防未完成。
一旦应用检查BQ端的作业是否完成,it can retrieve the data,处理它,并返回结果。
这将使过程更具幂等性和弹性,并避免保持所有这些连接打开,这根本不可扩展。
使用这样的架构,您可以将其部署在您喜欢的任何地方(GAE、函数等),并且它应该仍然可以工作。为了便于使用,我会使用带有 Datastore 的 Google Cloud Functions(存储您的操作 ID),但在这种情况下,它主要取决于您更喜欢使用什么。
【讨论】:
嗨@Jofre,非常感谢您的指导。这现在开始变得非常有意义。在我的应用程序中,请求(低量,每天最多 50 个)将主要来自预定的 cron 作业,所以我想到的架构师是:- 使用 Pub / Sub 作为中介来存储查询作业 ID(而不是 Datastore )。 STEP1) cron job-1 调用端点(我的应用在应用引擎上运行)开始查询作业,将 BQ job.insert ID 发布到发布者 STEP2) cron job-2 在 10 分钟后调用另一个端点。 (最多重试 5 次),此端点中的代码充当订阅者,获取查询作业 ID,检查 job.get 状态,获取 job.getQueryResults 结果处理数据并将响应返回给 cron 作业调用者。我的问题是,Pub/Sub 文档说:“订阅者是非阻塞的,所以我们必须阻止主线程退出以允许它在后台处理消息。” - 意思是,我必须放置一个等待循环 1 分钟。订阅者端点中的左右(或 AppEngine 允许的任何最大客户端请求超时) 我要改变的是最后一个。要将计算的数据返回给最终用户,您不应该让一切都运行。处理完数据后,您可以存储结果(例如,在gs://<bucketId>/results/<jobId>
下的存储桶中),并直接访问它们,而不必保持线程打开以将结果返回给调用者。在工作反应的那一刻,一旦处理完成,您就会知道结果的位置,因此无需保持任何运行。
感谢 AFAIK 的更正,在创建作业 (job.insert
) 期间,您只能指定将查询结果存储在 BQ 表中。我还可以将查询结果目标指定为 GCS 存储桶吗?我已经完成了一半,但遇到了同样的挑战......以上是关于AppEng Py Flexi :: 长时间运行的请求 :: 502 错误的主要内容,如果未能解决你的问题,请参考以下文章
将视图插入表格 - 视图不需要很长时间才能运行 - 插入需要很长时间