【发布时间】:2016-01-22 17:10:05
【问题描述】:
我们有一个 cron 作业,它每小时在后端模块上运行并创建任务。 cron 作业在 Cloud SQL 数据库上运行查询,任务向其他服务器发出 HTTP 调用并更新数据库。通常它们运行良好,即使创建了数千个任务,但有时它会“卡住”并且日志中没有任何内容可以说明情况。 例如,昨天我们监控了 cron 作业,它创建了几十个任务然后它停止了,还有 8 个任务也卡在队列中。当很明显没有发生任何事情时,我们又运行了几次该过程,每次都成功完成。
一天后,原始任务被 DeadlineExceededException 杀死,然后显然在同一实例中运行的其他 8 个任务被杀死并显示以下消息: 处理此请求的进程遇到问题,导致它退出。这可能会导致一个新进程被用于对您的应用程序的下一个请求。如果您经常看到此消息,则可能是在应用程序初始化期间引发了异常。 (错误代码 104)
在进程被杀死之前,我们在日志中完全没有看到它们的记录,现在我们看到它们,在 DeadlineExceededException 之前没有任何日志记录,所以我们不知道它们在什么时候卡住了。 我们怀疑数据库中存在一些锁定,但我们在以下链接中看到查询有 10 分钟的限制,这样会导致进程比一天更快地失败:https://cloud.google.com/appengine/docs/java/cloud-sql/#Java_Size_and_access_limits
我们模块的类和缩放配置是:
<instance-class>B4</instance-class>
<basic-scaling>
<max-instances>11</max-instances>
<idle-timeout>10m</idle-timeout>
</basic-scaling>
队列的配置是:
<rate>5/s</rate>
<max-concurrent-requests>100</max-concurrent-requests>
<mode>push</mode>
<retry-parameters>
<task-retry-limit>5</task-retry-limit>
<min-backoff-seconds>10</min-backoff-seconds>
<max-backoff-seconds>200</max-backoff-seconds>
</retry-parameters>
我为 cron 作业上传了一些跟踪数据的图像: http://imgur.com/a/H5wGG。 这包括跟踪摘要和时间线的开始/结束。 8 个终止的任务没有跟踪数据。
这可能是什么原因,我们如何进一步调查?
【问题讨论】:
-
您能否尝试启用Cloud Trace,然后包含您的慢请求之一的跟踪?
-
@David 我编辑了我的问题以包含 cron 作业的跟踪数据:imgur.com/a/H5wGG。他包括跟踪摘要和时间线的开始/结束。 8 个终止的任务没有跟踪数据。
-
标准做法是首先隔离问题。您可以对数据库进行查询并查看查询运行需要多长时间吗?使用 Google App Engine 可能并不直接,因此您可能希望在将本地计算机的 IP 授权给 Cloud SQL 实例等之后从本地计算机运行查询。
-
24 小时超时是因为您使用的是手动缩放。您包含的跟踪排除了一些 API 问题,但不排除云 sql(由于它不是简单的请求-响应协议,因此不会显示在跟踪中)。接下来,您可能想在进程挂起时尝试在 Cloud SQL 主机上“显示进程列表”,以查看它是否已连接/它在做什么。这将使我们能够确定它是否由于缓慢的 Cloud SQL 查询或死锁而挂起。
-
@David 现在有些任务已经卡了几个小时。 “SHOW PROCESSLIST”显示了 17 行,其中命令为“Sleep”,用户为“root”,主机为“localhost”。其中 8 个“时间”为 10199(2+ 小时),8 个“时间”为 8656(2+ 小时),1 个“时间”为 243(4 分钟,最后一个不断更新)。这些是“SHOW PROCESSLIST”的唯一结果,除了显示我运行此查询的记录。此服务器上没有正在处理的其他请求。
标签: java google-app-engine cron google-cloud-sql task-queue