How to configure Amazon queue service consuming count
I've been coding some mass mailing script. It's working like this.
1. Pull users from database who must receive email. Currently this count is ~11k.
2. Put their email address in Amazon queue service.
3. Trigger another Lambda code which pulls from queue service, with interval.
4. Find each user's related products and build html template (Amazon s3) for mailing.
5. Send them with Amazon SES.
Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.
Current code snippet:
module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});
app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};
function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);
find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}
Error message:
2018-11-21T01:51:11.039Z daf6727a-ed2f-11e8-9330-c581beef6958 { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }
amazon-web-services npm aws-lambda amazon-sqs amazon-ses
add a comment |
I've been coding some mass mailing script. It's working like this.
1. Pull users from database who must receive email. Currently this count is ~11k.
2. Put their email address in Amazon queue service.
3. Trigger another Lambda code which pulls from queue service, with interval.
4. Find each user's related products and build html template (Amazon s3) for mailing.
5. Send them with Amazon SES.
Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.
Current code snippet:
module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});
app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};
function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);
find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}
Error message:
2018-11-21T01:51:11.039Z daf6727a-ed2f-11e8-9330-c581beef6958 { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }
amazon-web-services npm aws-lambda amazon-sqs amazon-ses
Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 '18 at 2:46
When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 '18 at 3:58
It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You seemodule.exports.mail_puller
it's pulling code which is working not intentional way.
– Gereltod
Nov 21 '18 at 4:17
add a comment |
I've been coding some mass mailing script. It's working like this.
1. Pull users from database who must receive email. Currently this count is ~11k.
2. Put their email address in Amazon queue service.
3. Trigger another Lambda code which pulls from queue service, with interval.
4. Find each user's related products and build html template (Amazon s3) for mailing.
5. Send them with Amazon SES.
Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.
Current code snippet:
module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});
app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};
function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);
find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}
Error message:
2018-11-21T01:51:11.039Z daf6727a-ed2f-11e8-9330-c581beef6958 { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }
amazon-web-services npm aws-lambda amazon-sqs amazon-ses
I've been coding some mass mailing script. It's working like this.
1. Pull users from database who must receive email. Currently this count is ~11k.
2. Put their email address in Amazon queue service.
3. Trigger another Lambda code which pulls from queue service, with interval.
4. Find each user's related products and build html template (Amazon s3) for mailing.
5. Send them with Amazon SES.
Since Amazon SES only allowing maximum of 14 email per second, I have to configure consuming count while pulling. But it's somehow consuming too much and SES giving me error.
Current code snippet:
module.exports.mail_puller = (event, context, callback) => {
init_aws();
const Consumer = require('sqs-consumer');
const app = Consumer.create({
queueUrl: process.env.QUEUE_URL,
handleMessage: (msg, done) => {
build_email(JSON.parse(msg.Body));
done();
},
waitTimeSeconds: 20,
size: 1,
visibilityTimeout: 1,
sqs: sqs
});
app.on('error', (err) => {
if (err) console.log(err);
});
app.on('empty', (err) => {
if (err) console.log(err);
if (connection && connection.state !== 'disconnected') connection.end();
app.stop();
callback(null, response);
});
app.start();
};
function build_email(obj) {
init_cheerio();
const $t = cheerio.load(obj.tpl);
find_chosen(obj.id).then(products => {
for (let product of products) {
$t('.products-container').prepend(build_product(obj.product_tpl, product));
}
send_email(obj.email, obj.subject, $t.html().toString(), obj.id);
});
}
Error message:
2018-11-21T01:51:11.039Z daf6727a-ed2f-11e8-9330-c581beef6958 { Throttling: Maximum sending rate exceeded.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
message: 'Maximum sending rate exceeded.',
code: 'Throttling',
time: 2018-11-21T01:51:11.039Z,
requestId: 'ebcebbd1-ed2f-11e8-b6d5-130ef17efa56',
statusCode: 400,
retryable: true }
amazon-web-services npm aws-lambda amazon-sqs amazon-ses
amazon-web-services npm aws-lambda amazon-sqs amazon-ses
asked Nov 21 '18 at 2:17
Gereltod
87661633
87661633
Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 '18 at 2:46
When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 '18 at 3:58
It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You seemodule.exports.mail_puller
it's pulling code which is working not intentional way.
– Gereltod
Nov 21 '18 at 4:17
add a comment |
Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 '18 at 2:46
When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 '18 at 3:58
It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You seemodule.exports.mail_puller
it's pulling code which is working not intentional way.
– Gereltod
Nov 21 '18 at 4:17
Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 '18 at 2:46
Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 '18 at 2:46
When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 '18 at 3:58
When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 '18 at 3:58
It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see
module.exports.mail_puller
it's pulling code which is working not intentional way.– Gereltod
Nov 21 '18 at 4:17
It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see
module.exports.mail_puller
it's pulling code which is working not intentional way.– Gereltod
Nov 21 '18 at 4:17
add a comment |
1 Answer
1
active
oldest
votes
Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.
You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email
calls to reduce SES throttling.
Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404430%2fhow-to-configure-amazon-queue-service-consuming-count%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.
You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email
calls to reduce SES throttling.
Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.
add a comment |
Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.
You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email
calls to reduce SES throttling.
Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.
add a comment |
Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.
You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email
calls to reduce SES throttling.
Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.
Throttling is a normal event, and you should handle this exception by redriving the throttled request after some delay - AWS provides a retry policy framework for doing this (the link is for Java SDK, but similar concept exists for all SDKs). More reading on retries available here.
You can help mitigate this by doing some rate limiting on your side too - basically add some artificial delays to your send_email
calls to reduce SES throttling.
Experiment with different configurations of retry policy & client rate limiting to determine which numbers give you the best results for your use case.
answered Nov 27 '18 at 0:28
Krease
11.3k74059
11.3k74059
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404430%2fhow-to-configure-amazon-queue-service-consuming-count%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can’t you just limit the max concurrency of your lambda function?
– Matthew Pope
Nov 21 '18 at 2:46
When you say "Trigger another Lambda code which pulls from queue service, with interval", does that code only pull and process one message, or does it keep looping and processing multiple messages?
– John Rotenstein
Nov 21 '18 at 3:58
It should pull multiple messages but not exceeds 14 per seconds which is SES limitation. It should work on Cron schedule, and will pull whenever there are message in pool. You see
module.exports.mail_puller
it's pulling code which is working not intentional way.– Gereltod
Nov 21 '18 at 4:17