【问题标题】:A mailing platform using Amazon SES and Node js使用 Amazon SES 和 Node js 的邮件平台
【发布时间】:2015-12-25 14:48:13
【问题描述】:

我有一个案例,我需要使用亚马逊 SES 实现一个邮件平台。我决定使用 Node.js 来实现所需的并发性。

在 node js 应用程序中,我将从 redis 存储中获取我的所有联系人。 我特别要求的是我需要限制应用程序以特定的速率调用亚马逊的 api,比如每秒 x 封电子邮件,否则我将被亚马逊限制。任何人都可以建议我如何使用 Node.js 实现这种速率限制。我已经尝试了限制器包,但无法遵循确切的工作。也没有足够的文档可用。任何帮助将不胜感激。

【问题讨论】:

  • 请记住,任何试图限制调用次数而不考虑部署两次甚至更多相同类型节点的解决方案都是有缺陷的。您可以限制请求的数量,但以分布式方式执行此操作会更加困难。

标签: node.js amazon-web-services amazon-s3


【解决方案1】:

我有一个使用 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);

【讨论】:

    【解决方案2】:

    编辑 2: Underscore 已经实现了类似的功能,请查看 throttle function

    编辑:我用下面的代码制作了一个模块,请访问: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");
    });
    

    【讨论】:

    • 请注意,underscore 的 _.throttle() 函数会丢弃超过允许速率的呼叫 - 可能不是我们在发送电子邮件时想要的。
    【解决方案3】:

    nodemailer 据称允许您将速率限制设置为选项参数。

    nodemailer-ses-transport doc中所述:

    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
        } 
    });
    

    如您所见,设置起来非常简单。

    【讨论】:

      猜你喜欢
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 2022-01-23
      • 2016-12-10
      • 2015-08-09
      相关资源
      最近更新 更多