英文:
Handling duplicate requests due to cold starts in a Cloud Run API backend
问题
我目前正在使用Cloud Run API后端处理传入的HTTP POST请求。当系统一段时间没有活动时,它会进入“冷启动”状态。在冷启动期间收到新请求时,请求会被处理两次,导致重复操作。这种重复是不希望的,我正在寻找一个解决方案来防止它发生。
以下是系统的简化描述:
- API接收包含消息负载的HTTP POST请求。
- API处理请求,包括向外部服务发出搜索请求并返回搜索结果。
尽管这个过程看起来很简单,但日志显示,在冷启动期间,传入的请求会被处理两次。
至今我尝试过以下方法:
-
立即返回响应:一旦接收到POST请求,我尝试立即向发送方返回响应,然后继续在后台任务中处理请求。然而,这并没有解决问题,因为请求仍然会被处理两次。
-
创建临时集合并存储来自POST请求的message_ids,以便如果获得相同的message_id,可以与集合进行比对并忽略它。
当我创建第二种机制时,我以为问题已解决,但实际上它没有捕获到问题。
以下是我的日志的简化版本:
- 时间戳1
- POST请求1处理
- 时间戳2
- 服务器进程已启动
- 等待应用程序启动
- 应用程序启动完成
- Uvicorn运行在http://0.0.0.0:8080上(按CTRL+C退出)
- 默认的启动TCP探测在容器“message-1”的端口8080上尝试1次后成功。
- 传入请求:POST [{“type”:“inbound”,“message_id”:1935379776,...}]
- 时间戳3
- 消息已处理
- ...
- 时间戳N
- POST请求2处理
- 时间戳N+1
- 传入请求:POST [{“type”:“inbound”,“message_id”:1935379776,...}]
- 时间戳N+2
- 消息已处理
- ...
- 关机日志
正如您所看到的,相同的POST请求出现两次,我正在检查message_id,但仍然会处理两次。
一个特别有趣的事情可能有所帮助,我使用了两个不同的第三方API。一个是google_search,另一个是用于发送消息的API。
如果您有任何关于如何解决这个问题的建议,请告诉我。
英文:
I am currently working with a Cloud Run API backend that processes incoming HTTP POST requests. When the system has been idle for some time, it goes into a "cold start". Upon receiving a new request during a cold start, the request is processed twice, resulting in duplicate actions. This duplication is not desirable and I am looking for a solution to prevent it.
Here is a simplified description of the system:
The API receives an HTTP POST request containing a message payload.
The API processes the request, which involves making a search request to an external service and returning the search result.
Despite this seemingly straightforward process, the logs show that during a cold start, the incoming request is processed twice.
Here's what I've tried so far:
-
Returning a response immediately: As soon as the POST request is received, I tried returning a response to the sender, and then proceeding to process the request in a background task. However, this did not solve the issue, as the request is still being processed twice.
-
Creating a temporary set and storing the message_ids from the post request so if I get the same message_id I can check with the set and ignore it.
So when I created the second mechanism I thought I solved it however it's not catching it.
Here is also a simplified version of my logs:
2023-06-15 21:00:58.675 BST
POST200660 B5 msUnknown https://my-cloud-run-app.com/message
2023-06-15 21:01:00.485 BST
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
Default STARTUP TCP probe succeeded after 1 attempt for container "message-1" on port 8080.
Incoming request: POST [{"type":"inbound","message_id":1935379776,...}]
2023-06-15 21:01:25.539 BST
Message Processed.
...
2023-06-15 21:02:16.550 BST
POST200660 B7 msUnknown https://my-cloud-run-app.com/message
2023-06-15 21:02:16.560 BST
Incoming request: POST [{"type":"inbound","message_id":1935379776,...}]
2023-06-15 21:02:16.563 BST
Message Processed.
...
2023-06-15 21:17:31.301 BST
INFO: Shutting down
2023-06-15 21:17:31.403 BST
INFO: Waiting for application shutdown.
2023-06-15 21:17:31.403 BST
INFO: Application shutdown complete.
2023-06-15 21:17:31.404 BST
INFO: Finished server process [1]
As you can see same post request comes twice and I'm checking the message_id but still It makes it.
One particularly interesting things which might help is I'm using 2 different 3rd party API.
One is google_search.
The other is for sending the message.
Although it shows that it process the Message twice It only sends one request to google_search but twice to SMS API
答案1
得分: 1
看起来请求被发送了两次,因为在第一次请求期间,将接收请求的实例尚未启动。为了防止这种情况,您可以使用最小实例设置为您的服务启用空闲实例。默认情况下,实例在处理完所有请求后会保持空闲状态15分钟,然后关闭,但通过启用min-instance
,您可以保持一个或多个实例处于空闲状态,以减小冷启动的影响。您可以参考此文档了解有关最小实例以及如何启用它的更多信息。
英文:
It seems that the request is being sent twice because during the 1st request the instance that's going to receive it is not started. To prevent this you can enable idle instance for your service using the minimum instance setting. By default, instances are kept idle for 15 mins before shutting down after all requests are handled, but by enabling min-instance
, you can keep one or more instances idle to minimize the impact of cold starts. You can refer to this document for more information about minimum instances and how to enable it.<br><br>
答案2
得分: 0
我通过在冷启动时添加 CPU 提升来解决了这个问题。这有助于我避免超时,因此我没有收到重复的消息。
您可以将此添加到您的 gcloud 部署函数中,如下所示:
gcloud run deploy <YOUR SERVICE> --image etc... --cpu-boost
英文:
I solved the issue by adding a cpu-boost to my cold-start. This helped me to not to hit timeout so I didn't get duplicate messages.
You can add that to your gcloud deploy function as follows:
gcloud run deploy <YOUR SERVICE> --image etc... --cpu-boost
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论