AWS SQS + API网关+ Lambda + DB

问题描述 投票:0回答:2

我使用API​​ Gateway + Lambda + DB。

如果发出许多请求,则会发生连接错误。

为了测试,我不想增加最大连接选项。

是否可以使用SQS - > Lambda - > API网关 - > Lambda - > DB?

或者其他方式?

amazon-web-services aws-lambda aws-api-gateway amazon-sqs
2个回答
2
投票

首先,确保在每次调用lambda时都不要创建新连接。您应该在lambda处理程序之外创建连接(因此它将在初始化时创建),或使用连接池。

通过这样做,到DB的连接数将与并发调用的数量相同。

您可以将lambda的并发限制设置为对活动连接有限制(但这意味着当您到达时,由于并发限制,触发lambda可能会失败)。

您可以使用SQS触发lambda,并且在达到并发限制的情况下,请求将排队,直到先前的请求结束。

在没有为lambda设置并发限制的情况下使用SQS将无法解决问题,因为并发调用(=活动连接)的数量仍然很高。

做“SQS - > Lambda - > API网关 - > Lambda - > DB”这样的事情我没有看到任何好处。可能的用例是'API Gateway - > SQS - > Lambda'。

您也可以使用'API Gateway - > Lambda'来设置lambda并发限制。在这种情况下,对API网关的一些调用可能会失败,应该使用exponential backoff重试。


0
投票

是否可以使用SQS - > Lambda - > API网关 - > Lambda - > DB?

答:是的,你可以这样做,请找到以下示例用api getway url替换你的呼叫,然后点击休息呼叫,但不能解决你的问题。

var https = require('https');
       exports.handler = (event, context, callback) => {
       var params = {
                    host: "bittrex.com",
                    path: "/api/v1.1/public/getmarketsummaries"

                    };

  var req = https.request(params, function(res) {
    let data = '';
    console.log('STATUS: ' + res.statusCode);
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
        data += chunk;
    });
    res.on('end', function() {
        console.log("DONE");
        console.log(JSON.parse(data));
    });
  });
   req.end();
 };

其他方法:

执行Lambda函数后,AWS Lambda会维护执行上下文一段时间,以预期另一个Lambda函数调用。实际上,如果AWS Lambda选择在再次调用Lambda函数时重用上下文,则服务在Lambda函数完成后冻结执行上下文并解冻上下文以供重用。此执行上下文重用方法具有以下含义:

Lambda函数代码中的任何声明(在处理程序代码之外,请参阅编程模型)仍然初始化,在再次调用函数时提供额外的优化。例如,如果Lambda函数建立数据库连接,而不是重新建立连接,则在后续调用中使用原始连接。您可以在代码中添加逻辑,以在创建连接之前检查连接是否已存在。

示例:

import sys
import logging
import rds_config
import pymysql
#rds settings
rds_host  = "rds-instance-endpoint"
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name

logger = logging.getLogger()
logger.setLevel(logging.INFO)

try:
    conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
    logger.error("ERROR: Unexpected error: Could not connect to MySQL instance.")
    sys.exit()

logger.info("SUCCESS: Connection to RDS MySQL instance succeeded")
def handler(event, context):
    """
    This function fetches content from MySQL RDS instance
    """

    item_count = 0

    with conn.cursor() as cur:
        cur.execute("create table Employee3 ( EmpID  int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (EmpID))")  
        cur.execute('insert into Employee3 (EmpID, Name) values(1, "Joe")')
        cur.execute('insert into Employee3 (EmpID, Name) values(2, "Bob")')
        cur.execute('insert into Employee3 (EmpID, Name) values(3, "Mary")')
        conn.commit()
        cur.execute("select * from Employee3")
        for row in cur:
            item_count += 1
            logger.info(row)
            #print(row)
    conn.commit()

    return "Added %d items from RDS MySQL table" %(item_count)

在处理程序之外执行pymysql.connect()允许您的函数重用数据库连接以获得更好的性能。

© www.soinside.com 2019 - 2024. All rights reserved.