首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当收到太多MySQL查询请求时,Lambda函数"Error:“

问当收到太多MySQL查询请求时,Lambda函数"Error:“
EN

Stack Overflow用户
提问于 2019-03-28 19:27:42
回答 1查看 3.2K关注 0票数 1

我试图对我的AWS函数进行测试,该函数对RDS MySQL (t2.media)进行查询。但是,如果我多次请求API,虽然我可以用正确的数据成功地获得查询,但有时会导致"Error: connect“。

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

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

MySQL:

wait_timeout 1 max_connections 16000 interactive_timeout 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-458 b-a5b5-781cdfdd80df{错误:连接ETIMEDOUT 在Connection._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._onTimeout (net.js:420:8) 在超时(timers.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) Protocol._enqueue

在(/var/task/node_modules/mysql/lib/protocol/Protocol.js:51:23) Protocol.handshake

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

在(/var/task/node_modules/mysql/lib/Connection.js:453:10) Connection._implyConnect

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

(/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误差日志

209-03-28T18:18:49.378320Z9500注中止连接9500到db:'db‘用户:'user’主机:'123.123.123.123‘(超时读取通信数据包) 209-03-28T18:18:49.392514Z 9498注中止连接9498到db:'db‘用户:'user’主机:'123.123.123.123‘(超时读取通信数据包) 209-03-28T18:18:49.470617Z 9499注中止到db的连接9499:'db‘用户:'user’主机:'123.123.123.123‘(读取通信数据包超时) 2019年-03-28T18:18:49.636775Z 9501笔记中止连接9501到db:'db‘用户:'user’主机:'123.123.123.123‘(超时读取通信数据包) 209-03-28T18:18:49.694669Z9502注:中断连接9502到db:'db‘用户:'user’主机:'123.123.123.123‘(超时读取通信数据包) 2019年-03-28T18:18:49.803457Z 9503注中止到db的连接9503:'db‘用户:'user’主机:'123.123.123.123‘(超时读取通信数据包) 209-03-28T18:18:49.824250Z 9504注:中断到db的连接9504:'db‘用户:'user’主机:'123.123.123.123‘(读取通信数据包超时)

我对lambda的db.js查询

代码语言:javascript
复制
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脚本

代码语言:javascript
复制
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)
  })
}

编辑:我还试图在测试脚本中更改i<1,然后它总是给我“错误:连接ETIMEDOUT”。

index.js

代码语言:javascript
复制
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

代码语言:javascript
复制
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-28T23: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) Handshake._onTimeout 在(/var/task/node_modules/mysql/lib/protocol/Timer.js:32:23) Timer._onTimeout 在超时(timers.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) Protocol._enqueue

在(/var/task/node_modules/mysql/lib/protocol/Protocol.js:51:23) Protocol.handshake

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

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

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

在新的承诺中

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

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

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

致命的:没错,

超时: 10000 }

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

我< 100结果=>成功: 866和错误:134个请求。

我< 10结果=>成功:8和错误:2请求。

握手非活动超时时出错

db.js和con.createConnection在外面

代码语言:javascript
复制
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)
    })
  })
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-28 22:56:06

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

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

我建议在lambda初始化时(又名“coldstart”)创建连接,方法是将代码行let con = mysql.createConnection(dbParams)移出任何函数(这样只会发生一个连接)。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55405486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档