我有一个案例,我需要使用 amazon SES 实现一个邮件平台。我决定使用 Node.js 来实现所需的并发性。
在 node js 应用程序中,我将从 redis 存储中获取我的所有联系人。我特别要求的是我需要限制应用程序以特定的速率调用亚马逊的 api,比如每秒 x 封电子邮件,否则我将被亚马逊限制。任何人都可以建议我如何使用 Node.js 实现这种速率限制。我已经尝试了限制器包,但无法遵循确切的工作。也没有足够的文档可用。任何帮助将不胜感激。
我有一个案例,我需要使用 amazon SES 实现一个邮件平台。我决定使用 Node.js 来实现所需的并发性。
在 node js 应用程序中,我将从 redis 存储中获取我的所有联系人。我特别要求的是我需要限制应用程序以特定的速率调用亚马逊的 api,比如每秒 x 封电子邮件,否则我将被亚马逊限制。任何人都可以建议我如何使用 Node.js 实现这种速率限制。我已经尝试了限制器包,但无法遵循确切的工作。也没有足够的文档可用。任何帮助将不胜感激。
编辑 2: Underscore已经实现了类似的东西,看看油门功能。
编辑:我用下面的代码制作了一个模块,请访问:https ://github.com/gammasoft/rate-limited
这是一个非常简单的实现,可能会对您有所帮助。
参数:
1 .:包含params
要通过 SES 发送的电子邮件地址的数组
2 .:fn
一次发送一封电子邮件的函数
3 .:timeout
每次调用 之间的最短时间fn
,以毫秒为单位,例如:100 封电子邮件/秒然后你通过1000/100
(1 秒除以 100 封电子邮件)
4. callback
:当一切结束时调用的函数
代码
// rate-limit.js
var async = require("async");
module.exports = function(params, fn, timeout, callback){
var length = params.length;
var wait = function(cb){
if(--length === 0) return cb();
else setTimeout(function(){
cb();
}, timeout);
};
async.eachSeries(params, async.compose(wait, fn), function(err){
callback(err);
});
};
module.exports.timesPerSecond = function(times){
if(times === 0) throw new Error("Should not be zero");
return 1000/times;
};
module.exports.timesPerMinute = function(times){
if(times === 0) throw new Error("Should not be zero");
return (60 * 1000)/times;
};
用法
//test.js
var rateLimited = require("./rate-limit.js");
var timesPerMinute = rateLimited.timesPerMinute;
console.time("time");
rateLimited([1, 2, 3, 4, 5, 6], function(name, cb){
console.log(name);
cb();
}, timesPerMinute(5), function(err){
if(err) throw err;
console.timeEnd("time");
});
我有一个使用 mongodb 的类似设置。消息由各种应用程序排队到集合中,并由单独的节点应用程序处理。
var mongoose = require('mongoose'),
_ = require('underscore') ;
var BATCH_SIZE = 50;
var INTERVAL = 60000;
mongoose.connect('mongodb://localhost/outbox');
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var MessageSchema = new Schema({
to: {type:String},
subject: {type:String},
body: {type:String},
queued: {type:Date}
});
var Message = mongoose.model('Message',MessageSchema);
function processQueue(){
var query = Message.find({}).sort({queued: -1}).limit(BATCH_SIZE);
query.exec(function(err,messages){
if (err) return handleError(err);
if (!messages.length){
console.log('Queue is empty');
}else{
_.each(messages,function(msg){
sendTheSESMessage(msg, function(success){
if (success){
//remove from queue
msg.remove();
}else{
//handle it
}
})
});
}
});
}
setInterval(processQueue, INTERVAL);
据称, nodemailer允许您将速率限制设置为选项参数。
如nodemailer-ses-transport 文档中所述:
var transport = nodemailer.createTransport(sesTransport({
accessKeyId: "AWSACCESSKEY",
secretAccessKey: "AWS/Secret/key",
rateLimit: 5 // do not send more than 5 messages in a second
}));
设置好传输对象后,您可以像这样使用它,只需添加邮件选项来构建您的电子邮件(不必发送 html,请参阅nodemailer文档中的其他选项):
var mailOptions = {
from: 'CompanyName <info@mycompany.com>',
to: 'email@email.net',
subject: 'This is a subject',
html: '<h1>Some html here</h1>',
};
然后发送:
transporter.sendMail(mailOptions, function(error, info){
if(error){
// handle error
} else {
// handle success
}
});
如您所见,设置起来非常容易。