我有一个使用 Laravel/PHP 制作的应用程序。它使用 AWS API Gateway/Lambda 在无服务器架构上运行。
我的工作需要花费太多时间处理,这就是我使用 SQS 进行队列的原因。该作业调用外部 API,它发送一些文档,API 返回签名的文档,但是当它同时发送 5 个以上文档时,我可以在日志中看到以下内容:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>504 Gateway Timeout</title>
</head>
<body>
<h1>Gateway Timeout</h1>
<p>The gateway did not receive a timely response from the upstream server or application.</p>
</body>
</html>
而且我无法获得签名的文件,我使用 Guzzle 进行请求,它已指定:
'timeout' => 120
。
工作大约需要48秒
报告请求 ID:xxxx-xx-xxxx-x-xxx 持续时间:47.69 毫秒 已计费 持续时间:48 毫秒 内存大小:1024 MB 最大使用内存:78 MB 初始化 持续时间:399.67 毫秒
我不记得我在哪里读到过,如果即使AWS网关超时是30秒,如果它在SQS中添加作业那么就不会出现问题,对吗?
我能做什么?
编辑: 我刚刚编辑了实际的日志,确实花了30多秒,但是如果该作业在队列中应该没有问题?
我使用 Laravel Saloon 库来发出 http 请求,因为我正在构建很多 api,
这是我的工作:
<?php
namespace App\Jobs;
use App\Http\Saloon\Requests\CreateModuleJob;
use App\Models\Integration;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Arr;
class CreateModuleJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public array $information,
public string $module_id,
) {
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$request = new CreateModuleRequest($this->information);
///here takes more than 30 seconds
$response = $request->sendAsync()->then(
function ($response) {
//emit webhook
},
function ($response) {
//emit webhook
}
);
$response->wait();
}
}
我使用 spatie webhook 库来发出 webhook,这些 webhook 由节点应用程序接收,并且在节点应用程序中我编写了 console.log(data) 来查看发生了什么
lambda 日志返回以下内容:
2023-07-07T22:19:20.478Z xxxxx-xxx-4fxxxac-xx-xxINFO {
"app_id": "xxxxxxxxxxxxxxxxxxxx",
"event": "signature.failed",
"data": {
"response": "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>504 Gateway Timeout</title>\n</head><body>\n<h1>Gateway Timeout</h1>\n<p>The gateway did not receive a timely response\nfrom the upstream server or application.</p>\n</body></html>\n"
},
"metadata": []
}
在工作中我提出了一个需要 30 秒以上的请求?那就是问题所在?即使那份工作是在 SQS?
编辑2: 在向外部 api 发出请求之前,lambda 函数会向重定向服务器发出请求,为什么?因为外部api只能接受来自特定ip地址的请求,所以我们使用重定向服务器,超时是因为重定向服务器的lambda函数吗?
解决方案是增加saloon/guzzle库中的超时,我之前将其设置为120秒,但它需要更多的超时,所以我将其增加到300秒,现在它工作完美。所以我的建议是,尽管它使用 AWS Gateway,或者你的 lambda 日志显示一些奇怪的东西,只要你将该作业/任务放入队列中,你仍然可以增加超时,在我的例子中,我使用了 SQS