Alw*_*nny 5 python amazon-web-services amazon-ecs python-requests aws-fargate
我在 AWS Fargate 上使用 Amazon ECS,我的实例可以访问互联网,但连接在350秒后断开。平均而言,在 100 次中,我的服务收到ConnectionResetError: [Errno 104] Connection Reset by Peer Error 的次数大约有 5 次。我发现了一些建议来解决我的服务器端代码上的该问题,请参阅此处和此处
原因
如果使用 NAT 网关的连接空闲 350 秒或更长时间,连接就会超时。
当连接超时时,NAT 网关会向 NAT 网关后面尝试继续连接的任何资源返回 RST 数据包(它不会发送 FIN 数据包)。
解决方案
为了防止连接被丢弃,您可以通过该连接启动更多流量。或者,您可以在实例上启用 TCP keepalive,其值小于 350 秒。
现有代码:
url = "url to call http"
params = {
"year": year,
"month": month
}
response = self.session.get(url, params=params)
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我目前正在使用使用tenacity 的创可贴重试逻辑解决方案,
@retry(
retry=(
retry_if_not_exception_type(
HTTPError
) # specific: requests.exceptions.ConnectionError
),
reraise=True,
wait=wait_fixed(2),
stop=stop_after_attempt(5),
)
def call_to_api():
url = "url to call HTTP"
params = {
"year": year,
"month": month
}
response = self.session.get(url, params=params)
Run Code Online (Sandbox Code Playgroud)
所以我的基本问题是如何正确使用 python requests 来执行以下任何解决方案,
在 350 秒不活动之前关闭连接
为 TCP 连接启用 Keep-Alive
为未来在使用AWS Farget + NAT时遇到此问题的用户发布解决方案,
我们需要将 TCP keepalive 设置设置为服务器端配置指定的值,此 PR 对我解决问题有很大帮助: https: //github.com/customerio/customerio-python/pull/70/files
import socket
from urllib3.connection import HTTPConnection
HTTPConnection.default_socket_options = ( HTTPConnection.default_socket_options + [
(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
(socket.SOL_TCP, socket.TCP_KEEPIDLE, 300),
(socket.SOL_TCP, socket.TCP_KEEPINTVL, 60)
]
)
Run Code Online (Sandbox Code Playgroud)