Я пытаюсь провести тестирование моей лямбда-функции AWS, которая выполняет запрос к RDS MySQL (t2.medium).
Однако, если я запрашиваю API много раз, хотя я могу успешно получить запрос с правильными данными, это иногда приводит к «Ошибка: подключить ETIMEDOUT».
Что-то не так в моем коде или настройке?
Я прочитал несколько советов, чтобы установить некоторые параметры:
MySQL:
wait_timeout 1
max_connections 16000
interactive_timeout 6000
max_allowed_packet 1073741824
Lamdba:
Тайм-аут 60 сек. Поместите лямбда-функцию в тот же VPC, что и RDS
Добавлена политика выполнения VPC AWSLambdaVPCAccessExecutionRole
назначить группу безопасности для лямбда-функции
В безопасности, прикрепленной к экземпляру RDS, добавлено входящее правило
для mysql
Убедитесь, что функция Lambda имеет доступ к той же базе данных VPC RDS
Журнал лямбда-ошибок
2019-03-28T18: 51: 47.353Z ab4fbbaf-1ea2-458b-a5b5-781cdfdd80df {Ошибка:
подключить ETIMEDOUT
at Connection._handleConnectTimeout
* +1039 * (/ вар / задача / node_modules / MySQL / Библиотека / Connection.js: 411: 13)
в Object.onceWrapper (events.js: 313: 30)
at emitNone (events.js: 106: 13)
в Socket.emit (events.js: 208: 7)
в Socket._onTimeout (net.js: 420: 8)
в ontimeout (timers.js: 482: 11)
в tryOnTimeout (timers.js: 317: 5)
в Timer.listOnTimeout (timers.js: 277: 5)
в Protocol._enqueue
(/var/task/node_modules/mysql/lib/protocol/Protocol.js:144:48)
в Protocol.handshake
(/var/task/node_modules/mysql/lib/protocol/Protocol.js:51:23)
на Connection.connect
(/var/task/node_modules/mysql/lib/Connection.js:118:18)
at Connection._implyConnect
(/var/task/node_modules/mysql/lib/Connection.js:453:10)
в Connection.query
(/var/task/node_modules/mysql/lib/Connection.js:198:8)
на Promise (/var/task/db.js:62:9)
на новый Promise ()
в Object.retrieve (/var/task/db.js:55:10)
at exports.getAlerts (/var/task/index.js:59:24)
errorno: «ETIMEDOUT»,
код: 'ETIMEDOUT',
системный вызов: 'connect',
фатально: правда}
Журнал ошибок RDS
2019-03-28T18: 18: 49.378320Z 9500 [Примечание] Прерванное соединение 9500 в дБ:
'db' user: 'user' host: '123.123.123.123' (Получено время ожидания
пакеты связи)
2019-03-28T18: 18: 49.392514Z 9498 [Примечание] Прервано соединение 9498 с дБ:
'db' user: 'user' host: '123.123.123.123' (Получено время ожидания
пакеты связи)
2019-03-28T18: 18: 49.470617Z 9499 [Примечание] Прерванное соединение 9499 в дБ:
'db' user: 'user' host: '123.123.123.123' (Получено время ожидания
пакеты связи)
2019-03-28T18: 18: 49.636775Z 9501 [Примечание] Прервано соединение 9501 в дБ:
'db' user: 'user' host: '123.123.123.123' (Получено время ожидания
пакеты связи)
2019-03-28T18: 18: 49.694669Z 9502 [Примечание] Прервано соединение 9502 к дБ:
'db' user: 'user' host: '123.123.123.123' (Получено время ожидания
пакеты связи)
2019-03-28T18: 18: 49.803457Z 9503 [Примечание] Прервано соединение 9503 с дБ:
'db' user: 'user' host: '123.123.123.123' (Получено время ожидания
пакеты связи)
2019-03-28T18: 18: 49.824250Z 9504 [Примечание] Прервано соединение 9504 с дБ:
'db' user: 'user' host: '123.123.123.123' (Получено время ожидания
пакеты связи)
Мой запрос 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)
})
}
Edit:Я также пытался изменить i <1 в тестовом скрипте, затем он всегда выдает «Ошибка: подключите ETIMEDOUT. Но с i <900 он иногда работает успешно </p>
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-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)
в Handshake._onTimeout (/ var / task / node_modules / mysql / lib / protocol / sequence / Sequence.js: 124: 8)
в Timer._onTimeout (/var/task/node_modules/mysql/lib/protocol/Timer.js:32:23)
в ontimeout (timers.js): 482: 11)
в tryOnTimeout (timers.js: 317: 5)
в Timer.listOnTimeout (timers.js: 277: 5)
в Protocol._enqueue (/var/task/node_modules/mysql/lib/protocol/Protocol.js:144:48)
в Protocol.handshake (/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)
в Promise (/ var/task/db.js:72:10)
в новом Promise ()
в Object.retrieve (/var/task/db.js:67:10)
at exports.getAlerts (/var/task/index.js:59:24)
код: 'PROTOCOL_SEQUENCE_TIMEOUT',
неустранимый: true,
время ожидания:10000}
Установить сейчас с помощью пула и проверить его с помощью цикла запроса:
i <100 result => Success: 866 и Error: 134 request.
i <10 результат => Успешно: 8 и Ошибка: 2 запроса.
Ошибка с таймаутом неактивности рукопожатия
db.js с con.createConnection outside
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)
})
})
}