当前位置: 首页 > 知识库问答 >
问题:

当收到太多MySQL查询请求时,Lambda函数“错误:连接ETIMEDOUT”

杜俊楚
2023-03-14

我正在尝试对我的AWS lambda函数进行测试,该函数对RDS MySQL(t2.medium)进行查询。但是,如果我多次请求API,尽管我可以使用正确的数据成功查询,但有时会导致“错误:连接ETIMEDOut”。

我的代码或设置有问题吗?

我阅读了一些设置一些参数的建议:

MySQL:

wait_timeout 1

max_connections16000

交互式_超时6000

max_allowed_packet 1073741824

兰巴:

超时 60 秒将 Lambda 函数放在与您的 RDS 相同的 VPC 中

添加了VPC执行策略AWSLambdaVPCAccessExecutionRole

将安全组分配给lambda函数

在附加到RDS实例的安全性中,为mysql添加了一个入站规则

确认 Lambda 函数有权访问同一 VPC RDS 数据库

Lambda错误日志

2019-03-28T18:51:47.353Z ab4fbbaf-1ea2-458b-a5b5-781cdfdd80df{错误:连接ETIMEDOUT

在Connection._handleConnectTimeout

(/var/task/node_modules/mysql/lib/Connection.js:411:13)

Object.once包装(events.js:313: 30)

在emitNone (events.js:106:13)

在Socket.emit (events.js:208:7)

在插座上。_onTimeout (net.js:420:8)

超时时(计时器.js:482:11)

在tryOnTimeout (timers.js:317:5)

在Timer.listOnTimeout(timers.js:277: 5)

协议_排队(/var/task/node_modules/mysql/lib/protocol/protocol.js:144:48)

at protocol . handshake(/var/task/node _ modules/MySQL/lib/protocol/protocol . js:51:23)

at connection . connect(/var/task/node _ modules/MySQL/lib/connection . js:118:18)

在连接。_implyConnect(/var/任务/node_modules/mysql/lib/Connection.js:453: 10)

at Connection.query (/var/task/node_modules/mysql/lib/Connection.js:198:8)

在promise时(/var/task/db.js:62:9)

在新promise ()

Object.retrieve(/var/任务/db.js:55: 10)

at exports . get alerts(/var/task/index . js:59:24)

错误号:“ETIMEDOUT”,

代码:“ETIMEDOut”,

系统调用:'连接',

致命:真}

RDS错误日志

2019-03-28T18:18:49.378320Z 9500[注]中止连接9500到db:'db'用户:'user'主机:'123.123.123.123'(读取通信包超时)

2019-03-28T18:18:49.392514Z 9498[注意]中止连接9498到db:'db'user:'user'host:'123.123.123.123'(读取通信数据包超时)

2019-03-28T18:18:49.470617Z 9499[注意]中止连接9499到db:'db'user:'user'host:'123.123.123.123'(读取通信数据包超时)

2019-03-28T18:18:49.636775Z 9501 [注意] 中止与数据库的连接 9501:“db” 用户:“用户”主机:“123.123.123.123”(读取通信数据包超时)

2019-03-28T18:18:49.694669Z 9502[注]中止连接9502到db:'db'用户:'user'主机:'123.123.123.123'(读取通信包超时)

2019-03-28T18:18:49.803457Z 9503[注意]中止连接9503到db:'db'user:'user'host:'123.123.123.123'(读取通信数据包超时)

2019-03-28t 18:18:49.824250 z 9504[注意]中止9504到数据库的连接:“数据库”用户:“用户”主机:“123.123.123.123”(读取通信数据包超时)

我的数据库.js 对 lambda 的查询

const mysql = require('mysql')
let retrieve = (sql, objectArr, entityName) => {
      return new Promise((resolve, reject) => {
        let con = mysql.createConnection(dbParams)
        con.query(sql, objectArr, (err2, results) => {
          con.end()
          if (err2) {
            console.log(err2)
            return reject(new apiError.DatabaseError('An error occurred in retrieve'))
          }
          console.log('Data retrieve successfully')
          return resolve(results)
        })
      })
    }

我的测试.js脚本

const request = require('request')
let errorCount = 0
let success = 0

for (let i = 0; i < 4000; i++) {
  console.log('Send')
  request.get('https://myapi/users', {
    headers: {
      'client_id': 'app',
      'Content-Type': 'application/json'
    }
  }, (error, response, body) => {
    if (error) {
      console.log('some error')
      errorCount++
    } else {
      let jsonBody = JSON.parse(body)
      if (jsonBody.code === 0) {
        success++
      } else {
        errorCount++
      }
    }

    console.log('Success: ', success)
    console.log('Error: ', errorCount)
  })
}

编辑:我也试图改变我

index.js

const db = require('./db.js')
exports.getUsers = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false
  try {
    let sql = 'SELECT * FROM User'
    let abc = await db.retrieve(sql, [], 'user')

    let response = {
      statusCode: 200,
      abc: abc,
      code: 0
    }
    return response
  } catch (err) {
    console.log(err)
    errorHandler(err)
  }
}

带泳池的db.js

const mysql = require('mysql')
const constants = require('./constants.js')

let dbParams = {
  host: constants.SQL_CONNECTION_HOST,
  user: constants.SQL_CONNECTION_USER,
  password: constants.SQL_CONNECTION_PASSWORD,
  database: constants.SQL_CONNECTION_DATABASE,
  multipleStatements: true,
  maxConnections: 4
}

const pool = mysql.createPool(dbParams)
let retrieve = (sql, objectArr, entityName) => {
  return new Promise((resolve, reject) => {
    pool.getConnection((err1, con) => {
      if (err1) {
        console.log(err1)
        return reject(new apiError.DatabaseError('An error occurred in retrieve pool'))
      }
      console.log('Pool connect successfully')
      con.query(sql, objectArr, (err2, results) => {
        con.end()
        if (err2) {
          console.log(err2)
          return reject(new apiError.DatabaseError('An error occurred in retrieve'))
        }
        console.log('Data retrieve successfully')
        return resolve(results)
      })
    })
  })
}

使用池后的错误日志

2019-03-28t 23:35:24.144 z 91 b0fc 78-E4 D1-4fd 9-BDF 7-923715 b 165 c 0 {错误:握手不活动超时

在握手。(/var/任务/node_modules/mysql/lib/协议/Protocol.js:163: 17)

在emitNone (events.js:106:13)

握手时。发出(events.js:208:7)

at Handshake._onTimeout (/var/task/node_modules/mysql/lib/protocol/sequences/Sequence.js:124:8)

在计时器处。_ on time out(/var/task/node _ modules/MySQL/lib/protocol/timer . js:32:23)

超时时(计时器.js:482:11)

在tryOnTimeout (timers.js:317:5)

在Timer.listOnTimeout(timers.js:277: 5)

协议_排队(/var/task/node_modules/mysql/lib/protocol/protocol.js:144:48)

at protocol . handshake(/var/task/node _ modules/MySQL/lib/protocol/protocol . js:51:23)

PoolConnection.connect(/var/任务/node_modules/mysql/lib/Connection.js:118: 18)

位于pool . getconnection(/var/task/node _ modules/MySQL/lib/pool . js:48:16)

在Promise(/var/task/db.js:72:10)

在新promise ()

位于对象。检索(/var/task/db.js:67:10)

at exports . get alerts(/var/task/index . js:59:24)

代码:'PROTOCOL_SEQUENCE_TIMEOUT',

致命:真,

超时:10000 }

立即使用池设置并使用请求循环对其进行测试:

握手不活动超时错误

外部con.create连接的db.js

const mysql = require('mysql')
// initialize dbParams
let con = mysql.createConnection(dbParams)

let retrieve = (sql, objectArr, entityName) => {
  return new Promise((resolve, reject) => {
    con.query(sql, objectArr, (err2, results) => {
      //con.end() commet out connection end here 
      if (err2) {
        console.log(err2)
        return reject(new apiError.DatabaseError('An error occurred in retrieve'))
      }
      console.log('Data retrieve successfully')
      return resolve(results)
    })
  })
}

共有1个答案

葛哲彦
2023-03-14

问题中没有解释检索函数是如何在lambda函数中调用的。

尽管如此,它似乎会在测试中的每次迭代中执行,这会创建大量连接并可能解释您看到的行为。

我建议在lambda初始化时(也称为“coldstart”)通过移动代码let con=mysql来创建连接。createConnection(dbParams)位于任何函数之外(这样只会发生一个连接)。

另一个好的选择是使用连池。

 类似资料:
  • 我尝试通过应用服务器Glassfish和JPA连接到mysql数据库。 我的persistence.xml如下所示: 有什么问题?

  • 当python lambda函数被执行时,我会得到“Task timed Ut after 3.00 seconds”错误。我正在尝试同样的示例函数。当我尝试从eclipse中运行相同的代码时,它工作得很好,我可以看到查询结果。同样,我可以从本地机器Mysql工作台连接到db实例而没有任何问题。 我尝试为这个lambda函数创建一个具有完全管理员访问策略的角色,但即使这样,它也不能正常工作。db实

  • 我尝试通过应用服务器Glassfish和JPA连接到mysql数据库。 我的persistence.xml如下所示: mysql中的“max_connections”设置为600。这样就够了。 有什么问题?

  • 我编写了一个非常简单的烧瓶服务器。服务器响应并返回我的home.html。我在127.0.0.1:5000访问该网站 到现在一切都很好。 谢了!

  • 我正在我的SQL中使用一个查询。首先我用 我该怎么做才能让它快过2秒

  • 我使用MongoDbFactory用Java连接到mongodb。但mongo服务每小时至少抛出一次套接字异常。因此,我不得不重启mongodb服务来恢复操作。我认为这可能是因为从java到mongodb的连接未关闭,而且MongoDbFactory没有为我提供关闭连接的功能。如何确保在特定会话后关闭所有连接。 这是我正在使用的代码: } 和: