如何防止连接到 Amazon VPC 的 Lambda 函数超时?
2 分钟阅读
0
我想防止我的 AWS Lambda 函数与 Amazon Virtual Private Cloud(Amazon VPC)的连接超时。
概述
在没有响应的情况下在负载均衡器或 NAT 网关后面调用 Lambda 函数 API 调用可能是由于连接空闲超时问题造成的。TCP 流的负载均衡器空闲超时值为 350 秒。
如果 API 调用响应延迟是间歇性的或小于 350 秒,这可能是由于重试和超时问题造成的。有关详细信息,请参阅如何解决在使用 AWS SDK 调用 Lambda 函数时出现的重试和超时问题?
解决方法
为防止连接中断,可以启用值小于 350 秒的 TCP keepalive 来重置空闲超时。TCP keepalive 通过每 20 秒向前端和后端连接发送数据包来防止连接处于空闲状态。
您可以在类似如下内容的套接字对象上调用 setKeepAlive:
Node.js 14 和 Node.js 16
const http = require('http'); function invokeApi() { return new Promise(resolve => { var callback = function(response) { var str = ''; response.on('data', function (chunk) { str += chunk; }); response.on('end', function () { response = '**** ALB response: ' + str; resolve(response) }); } const url = 'http://<alb-dns>'; const myTimeout = 1000*60*15; // 15 minutes let req = http.get(url, callback); req.on('error', (e) => { console.error(`Got error: ${e.message}`); }); req.on('socket', function (socket) { socket.setKeepAlive(true, 1000); //set SO_KEEPALIVE socket.setTimeout(myTimeout); socket.on('timeout', function() { console.log('request is about to timeout'); req.abort(); }); }); req.end(); }) } exports.handler = async (event) => { let output = await invokeApi(); const response = { statusCode: 200, body: output, }; return response; };
Node.js 18
import * as http from "http" function invokeApi() { return new Promise(resolve => { var callback = function(response) { var str = ''; response.on('data', function (chunk) { str += chunk; }); response.on('end', function () { response = '**** ALB response: ' + str; resolve(response); }); } const url = 'http://<alb-dns>'; const myTimeout = 1000*60*15; // 15 minutes let req = http.get(url, callback); req.on('error', (e) => { console.error(`Got error: ${e.message}`); }); req.on('socket', function (socket) { socket.setKeepAlive(true, 1000); //set SO_KEEPALIVE socket.setTimeout(myTimeout); socket.on('timeout', function() { console.log('request is about to timeout'); req.abort(); }); }); req.end(); }) } export const handler = async(event) => { let output = await invokeApi(); const response = { statusCode: 200, body: output, }; return response; };
Python 3.x
import json import socket import requests from urllib3.connection import HTTPConnection HTTPConnection.default_socket_options = HTTPConnection.default_socket_options + [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)] def lambda_handler(event, context): try: r = requests.get("http://<alb-dns>",timeout=(5,900)) output = r.text except requests.RequestException as e: print(e) raise e return { "statusCode": 200, "body": json.dumps({ "message": output, }), }
使用适用于 Java2 的 AWS SDK,您可以传递一个预配置的 HTTP 客户端,如下所示:
LambdaClient awsLambda = LambdaClient.builder() .region(region .httpClient(ApacheHttpClient.builder() .tcpKeepAlive(true) .connectionTimeout(Duration.ofSeconds(5)) .connectionMaxIdleTime(Duration.ofMinutes(15)) .socketTimeout(Duration.ofMinutes(15)).build()) .build();
使用适用于 Python 的 Amazon SDK(Boto3)许您使用配置文件。创建包含以下内容的 .config 文件:
[default] tcp_keepalive=true
然后,在目录 /var/task/config 中使用 .config 文件的值创建一个 Lambda 环境变量 AWS_CONFIG_FILE。
有关详细信息,请参阅连接空闲超时。
相关信息
AWS 官方已更新 1 年前
没有评论
相关内容
- AWS 官方已更新 1 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 1 年前