#node.js #aws-lambda
#node.js #aws-lambda
Вопрос:
У меня есть функция lambda для приема изображений из корзины S3, получения некоторых метаданных, сохранения их в экземпляре AWS RDS, а затем повторной загрузки изображения. Должно быть просто, но я боюсь, что одно из следующих вызывает проблемы.
- Иногда создает дубликаты
- Иногда пропускает файлы
Похоже, это происходит с большими наборами изображений. Я загрузил ресурсы до 1000, и, похоже, он работает достаточно хорошо. 3000 кажется ненадежным. Функция не установлена на тайм-аут слишком рано (30 секунд должно быть в порядке), у нее хорошее выделение памяти 512 МБ (пожалуйста, скажите мне, если это ложные предположения. Я любитель в этом и новичок в Lambda, поэтому, пожалуйста, дайте мне знать, что, по вашему мнению, я сделал.
const AWS = require('aws-sdk')
const uuidv4 = require('uuid/v4');
AWS.config.update({
accessKeyId: 'XXX',
secretAccessKey: 'XXX'
})
const s3 = new AWS.S3({
signatureVersion: 'v4',
region: 'eu-west-2'
})
const hasha = require('hasha')
const { Pool, Client } = require('pg')
const pool = new Pool({
user: 'XXX',
host: 'XXX',
database: 'XXX',
password: 'XXX',
port: 5432,
})
exports.handler = async (event, context) => {
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/ /g, ' '));
console.log("Processing: " key)
//Get file
try {
const file = await s3.getObject({
Bucket: bucket,
Key: key
}).promise()
const hash = await hasha(file.Body, { algorithm: 'md5' })
const id = uuidv4()
newfile = await s3.putObject({
Bucket: 'XXX',
Key: id,
Body: file.Body,
ContentType: file.ContentType
}).promise()
var fileString = key.split('/')
var fileName = fileString[fileString.length - 1]
const text = 'INSERT INTO original(original_filename, mime, file_size, file_path, file_name, hash) VALUES($1, $2, $3, $4, $5, $6) RETURNING *'
const values = [fileName, file.ContentType, file.ContentLength, key, id, hash]
const res = await pool.query(text, values)
console.log(res.rows[0])
return "Done"
} catch (err) {
console.log("####### Error #######: ", err)
return "Error"
}
}
Я ожидаю, что будет загружено X файлов, и столько же будет в целевой корзине и в моей таблице БД. Это не всегда так, и сложно определить, где что-то идет не так. Я уверен, что есть более элегантный способ сделать это.
Комментарии:
1. Несколько вещей, которые я бы сделал с места в карьер — переместите
try {
, чтобы закрыть начало и добавить уникальное ограничение к таблице, в которую вы вставляете. Тогда вы будете получать ошибки при возникновении условий, которых вы хотите избежать, что упрощает отладку.2. Уникальные ограничения — хорошая идея. Не могли бы вы подробнее остановиться на идее расширения инструкции try? Я попробую, но мне очень хочется знать, какова логика.
3. Какие-либо ошибки в ваших журналах CloudWatch? Также проверьте ошибки и показатели продолжительности вашей лямбды, чтобы узнать, есть ли какие-либо тайм-ауты. Одна вещь, которая может объяснить дубликаты, — это тот факт, что в случае ошибки ваша лямбда повторит попытку (см. docs.aws.amazon.com/lambda/latest/dg/retries-on-errors.html ) и ваш лямбда-код может выйти из строя между
putObject
иpool.query
, что приведет к дублированию объектов в вашей целевой корзине.4. @JamieDunbar Я не вижу ничего плохого в этом раннем коде, но мне нравится быть уверенным, что он учтен, когда неизвестные ошибки могут повлиять на мой код.