AWS SES: как отправить большое количество писем (> 10000 одновременно) - PullRequest
3 голосов
/ 14 мая 2019

Я создаю службу отправки электронной почты (lambda, Nodejs), которая будет отправлять электронную почту на список адресов одновременно.

Из-за требования: каждый адрес получает различное содержимое электронной почты, я не могу отправить несколько электронных писем за один запрос, но по одному.

_array = ... // list of address + html content, > 10000 records
for (var i = 0; i < _array.length; i++) {
    var params = {
        Destination: {/* required */
            ToAddresses: [_array[i].email]
        },
        Message: {/* required */
            Body: { /* required */
                Html: {
                    Data: _array[i].html,
                    Charset: 'UTF-8'
                },
            },
            Subject: { /* required */
                Data: 'Your order detail', /* required */
                Charset: 'UTF-8'
            }
        },
        Source: "mytestemail@email.com"
    }

    let send = await ses.sendEmail(params).promise();

}

В настоящее время у меня нет таких больших данных для тестирования, но я протестировал 100-200 электронных писем, все работает, и для отправки электронной почты требуется 15-40 секунд. Математически, 10000 нужно более 25 минут для выполнения задачи. Следовательно, этот подход не масштабируется из-за ограничения времени ожидания лямбда в 15 минут

Любой лучший подход или предложение приветствуется.

Edit:

Решение от @Thales Minussi потрясающее, я реализовал его, и оно работает. Я отметил это как ответ, но, тем не менее, я приветствую все лучшие практики, направленные на решение этой проблемы. Делитесь, учитесь и кодируйте счастливо

1 Ответ

4 голосов
/ 14 мая 2019

НЕ РЕКОМЕНДУЕТСЯ: Что вы могли бы сделать, это распараллелить sendEmail вызовы. Таким образом, вы можете создать большой массив Promises, а затем использовать await Promises.all(yourPromisesArray), поэтому Node.js сделает все возможное, чтобы оптимизировать процесс на основе количества ядер, доступных на компьютере, на котором работает ваша лямбда-функция, то есть получить Лучше всего, вам нужно установить оперативную память Lambda на 3 ГБ (машина прямо пропорциональна объему оперативной памяти, что означает, что чем больше ОЗУ вы установили, тем лучше машина, на которой работает ваш код). Но это все еще неисправно , как сейчас мы говорим о 10000 электронных писем, но что, если это число возрастет до 100000? 1000000? Это просто решение, которое недостаточно масштабируется для удовлетворения спроса по мере его роста, поэтому этого недостаточно. Другое дело, что если что-то пойдет не так (как, например, одно обещание не сработало), то его действительно сложно восстановить.

РЕКОМЕНДУЕТСЯ: Вместо этого я предлагаю вам использовать SQS для отделения функций, которые создают тела электронной почты, от функции, которая фактически отправляет ее, так что, короче говоря, вместо того, чтобы вызывать await ses.sendEmail(params).promise(), как вы делали выше, вы бы вместо этого поместили это сообщение в очередь SQS (с учетом ограничения в 256 КБ на сообщение) и подписали другую лямбду на эту очередь SQS. Каждая Lambda может считывать до 10 сообщений из SQS (и каждое сообщение может содержать много электронных писем), что значительно ускоряет процесс, особенно потому, что по умолчанию ваши функции Lambda будут масштабироваться для удовлетворения спроса.

Давайте выполним простую математику: если вы отправляете 100 сообщений в SQS, и каждое сообщение имеет 10 электронных писем, это означает, что в лучшем случае 10 лямбда-символов будут раскручиваться, каждый из которых потребляет пакет из 10 сообщений, но, как сообщение содержит 10 электронных писем, каждая лямбда будет обрабатывать 100 электронных писем, поэтому вы будете обрабатывать 1000 электронных писем в мгновение ока!

Важно отметить, что не все Lambdas будут собирать партии по 10 каждый раз, они могут собирать меньшие партии, поэтому может случиться так, что одновременно будет запущено более 10 функций Lambda, но я думаю, вы получите идея параллельной обработки

РЕДАКТИРОВАТЬ : поскольку электронные письма могут состоять из больших полезных нагрузок (изображений, длинных строк и т. Д.), Я предлагаю отправлять только соответствующую информацию в очередь SQS для оптимизации размер полезной нагрузки. Если вам нужны изображения или некоторые заранее определенные шаблоны для обработки, просто отправьте их соответствующие местоположения на S3 (или в другое хранилище, которое вы можете использовать), чтобы Lambda, которая фактически отвечает за отправку электронных писем, была той, которая выбирает эту информацию. и добавляет это к телу. По сути, ваше сообщение в SQS должно содержать только метаданные, чтобы максимально облегчить полезную нагрузку, чтобы вы могли воспользоваться преимуществом в 256 КБ в свою пользу. Что-то вроде этого должно быть достаточно, чтобы вывести вас из строя:

{
    "to": "to@email.com",
    "images": ["s3://bucket/image.jpg", "s3://bucket/image2.jpg"],
    "template": "s3://bucket/template.html"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...