Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“Lambda函数”;错误:连接ETIMEDOUT“;当收到太多MySQL查询请求时_Mysql_Node.js_Aws Lambda_Load Testing_Serverless - Fatal编程技术网

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

“Lambda函数”;错误:连接ETIMEDOUT“;当收到太多MySQL查询请求时,mysql,node.js,aws-lambda,load-testing,serverless,Mysql,Node.js,Aws Lambda,Load Testing,Serverless,我正在尝试对我的AWS lambda函数进行测试,该函数对RDS MySQL(t2.medium)进行查询。 但是,如果我多次请求API,尽管我可以使用正确的数据成功地获得查询,但有时会导致“错误:connect-ETIMEDOUT” 我的代码或设置是否有任何错误 我阅读了一些设置一些参数的建议: MySQL: 等待超时1 最大连接数16000 交互式超时6000 允许的最大数据包1073741824 拉姆达: 超时60秒将Lambda函数放置在与RDS相同的VPC中 添加了VPC执行策略AWS

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

我的代码或设置是否有任何错误

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

MySQL:

等待超时1

最大连接数16000

交互式超时6000

允许的最大数据包1073741824

拉姆达:

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

添加了VPC执行策略AWSLambdaVPCAccessExecutionRole

将安全组分配给lambda函数

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

确认Lambda功能访问同一VPC RDS数据库

Lambda错误日志

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

在连接时。\u handleConnectTimeout

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

在Object.onceWrapper(events.js:313:30)

在emitNone(events.js:106:13)

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

在Socket.\u onTimeout(net.js:420:8)

在ontimeout(timers.js:482:11)

在tryOnTimeout(timers.js:317:5)

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


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

按协议握手 (/var/task/node_modules/mysql/lib/protocol/protocol.js:51:23)

连接 (/var/task/node_modules/mysql/lib/Connection.js:118:18)

在连接处。\u暗示连接 (/var/task/node_modules/mysql/lib/Connection.js:453:10)

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

承诺时(/var/task/db.js:62:9)

在新的承诺()

在Object.retrieve(/var/task/db.js:55:10)

在exports.getAlerts(/var/task/index.js:59:24)

错误号:“ETIMEDOUT”

代码:“ETIMEDOUT”

系统调用:“连接”

致命的:真的}

RDS错误日志

2019-03-28818:18:49.378320Z 9500[注]终止了9500到db的连接: “db”用户:“用户”主机:“123.123.123.123”(读取超时 通信数据包)

2019-03-28818:18:49.392514Z 9498[注]中止了9498到db的连接: “db”用户:“用户”主机:“123.123.123.123”(读取超时 通信数据包)

2019-03-28818:18:49.470617Z 9499[注]中止了9499到db的连接: “db”用户:“用户”主机:“123.123.123.123”(读取超时 通信数据包)

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

2019-03-28818:18:49.694669Z 9502[注]中止了9502到db的连接: “db”用户:“用户”主机:“123.123.123.123”(读取超时 通信数据包)

2019-03-28818:18:49.803457Z 9503[注意]中止了9503到db的连接: “db”用户:“用户”主机:“123.123.123.123”(读取超时 通信数据包)

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

我对lambda的db.js查询

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)
        })
      })
    }
我的test.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)
  })
}
带池的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-28223:35:24.144Z 91b0fc78-e4d1-4fd9-bdf7-923715b165c0{错误: 握手不活动超时

握手时。 (/var/task/node_modules/mysql/lib/protocol/protocol.js:163:17)

在emitNone(events.js:106:13)

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

握手的时候 (/var/task/node_modules/mysql/lib/protocol/sequences/Sequence.js:124:8)

准时 (/var/task/node_modules/mysql/lib/protocol/Timer.js:32:23)

在ontimeout(timers.js:482:11)

在tryOnTimeout(timers.js:317:5)

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


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

按协议握手 (/var/task/node_modules/mysql/lib/protocol/protocol.js:51:23)

在PoolConnection.connect (/var/task/node_modules/mysql/lib/Connection.js:118:18)

在Pool.getConnection(/var/task/node_modules/mysql/lib/Pool.js:48:16)

承诺时(/var/task/db.js:72:10)

在新的承诺()

在Object.retrieve(/var/task/db.js:67:10)

在exports.getAlerts(/var/task/index.js:59:24)

代码:“协议\序列\超时”

致命的:是的

超时:10000}

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

i<100 result=>成功:866次,错误:134次请求

i<10 result=>Success:8和Error:2请求

握手不活动超时时出错

db.js,外部带有con.createConnection

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)
    })
  })
}

在lambda函数中如何调用
retrieve
函数的问题中没有解释

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

我建议在lambda初始化时(也称为“coldstart”)创建连接,方法是将代码行
let con=mysql.createConnection(dbParams)
移动到任何函数之外(以便只发生一个连接)

另一个好的选择是使用。

多少次是“大量次数”a
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)
    })
  })
}