Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Email 来自数据库的SMS和电子邮件队列_Email_Amazon Web Services_Rds - Fatal编程技术网

Email 来自数据库的SMS和电子邮件队列

Email 来自数据库的SMS和电子邮件队列,email,amazon-web-services,rds,Email,Amazon Web Services,Rds,我只是想讨论一下我面临的一种情况 我想向用户发送电子邮件-很多电子邮件-但如果我在应用程序运行时发送电子邮件,AWS SDK对电子邮件的速度很慢-糟糕的用户体验-至少对我的应用程序如此 因此,我计划在数据库中输入数据(电子邮件地址、要发送的内容、0),然后启动cron作业来读取表并开始发送电子邮件—一旦发送电子邮件—它将数据库行标记为1 我在某个地方读到一个错误的做法,导致数据库服务器过载 是的,我会使用智能cron,这样就不会有两个cron重叠,或者为偶数和奇数等设置一个cron。我也在寻找第

我只是想讨论一下我面临的一种情况

我想向用户发送电子邮件-很多电子邮件-但如果我在应用程序运行时发送电子邮件,AWS SDK对电子邮件的速度很慢-糟糕的用户体验-至少对我的应用程序如此

因此,我计划在数据库中输入数据(电子邮件地址、要发送的内容、0),然后启动cron作业来读取表并开始发送电子邮件—一旦发送电子邮件—它将数据库行标记为1

我在某个地方读到一个错误的做法,导致数据库服务器过载

是的,我会使用智能cron,这样就不会有两个cron重叠,或者为偶数和奇数等设置一个cron。我也在寻找第三方替代方案,比如cron


是否有人可以分享他们在类似情况下的经验等。我只想使用智能解决方案,而不仅仅是在数据库上投入大量资源和在事务上花费大量资金……

我必须做一些类似的事情,并按照Charles Engelke的建议做——我使用了SQS

通过将整个消息内容放在SQS消息中,我完全消除了数据库。您仅限于,所以只要这不是一个问题,这种方法是可能的

下面是将消息排队的示例代码:

package com.softwareconfidence.bsp.sending;

import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.googlecode.funclate.json.Json;

import java.util.HashMap;
import java.util.Map;

public class EmailQueuer  {
    private final AmazonSQS sqs;
    private final String sendQueueUrl;

    public EmailQueuer(AmazonSQS sqs,String sendQueueUrl) {
        this.sqs = sqs;
        this.sendQueueUrl = sendQueueUrl;
    }

    public void queue() {
        Map<String,String> emailModel = new HashMap<String, String>(){{
            put("from","me@me.com");
            put("to","you@you.com");
            put("cc","her@them.com");
            put("subject","Greetings");
            put("body","Hello World");
        }}; 
        sqs.sendMessage(new SendMessageRequest(sendQueueUrl, Json.toJson(emailModel)));
    }
}
当应用程序退出时,您需要确保在此执行器上调用shutdown()。无论如何,此行每分钟都会发送电子邮件,其中sendEmails()返回此可运行类的一个实例:

package com.softwareconfidence.bsp.standalone.sending;

import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.model.*;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.model.DeleteMessageRequest;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.amazonaws.services.sqs.model.ReceiveMessageResult;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.googlecode.funclate.json.Json;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;

public class FromSqsEmailer implements Runnable {
    private final AmazonSQS sqs;
    private final String sendQueueUrl;
    private final String deadLetterQueueUrl;
    private final AmazonSimpleEmailService emailService;

    public FromSqsEmailer(AmazonSimpleEmailService emailService, String deadLetterQueueUrl, String sendQueueUrl, AmazonSQS sqs) {
        this.emailService = emailService;
        this.deadLetterQueueUrl = deadLetterQueueUrl;
        this.sendQueueUrl = sendQueueUrl;
        this.sqs = sqs;
    }

    public void run() {
        int batchSize = 10;
        int numberHandled;
        do {
            ReceiveMessageResult receiveMessageResult =
                    sqs.receiveMessage(new ReceiveMessageRequest(sendQueueUrl).withMaxNumberOfMessages(batchSize));
            final List<com.amazonaws.services.sqs.model.Message> toSend = receiveMessageResult.getMessages();
            for (com.amazonaws.services.sqs.model.Message message : toSend) {
                SendEmailResult sendResult = sendMyEmail(Json.parse(message.getBody()));
                if(sendResult != null) {
                    sqs.deleteMessage(new DeleteMessageRequest(sendQueueUrl, message.getReceiptHandle()));
                }
            }
            numberHandled = toSend.size();
        } while (numberHandled > 0);
    }

    private SendEmailResult sendMyEmail(Map<String, Object> emailModel) {
        Destination to = new Destination()
                .withToAddresses(get("to", emailModel))
                .withCcAddresses(get("cc", emailModel));
        try {
            return emailService.sendEmail(new SendEmailRequest(get("from", emailModel), to, body(emailModel)));
        } catch (Exception e){
            StringWriter stackTrace = new StringWriter();
            e.printStackTrace(new PrintWriter(stackTrace));
            sqs.sendMessage(new SendMessageRequest(deadLetterQueueUrl, "while sending email " + stackTrace));
        }
        return null;
    }

    private String get(String propertyName, Map<String, Object> emailModel) {
        return emailModel.get(propertyName).toString();
    }

    private Message body(Map<String, Object> emailModel) {
        Message message = new Message().withSubject(new Content(get("subject", emailModel)));
        Body body = new Body().withText(new Content(get("body", emailModel)));
        message.setBody(body);
        return message;
    }
}
package com.softwareconsidence.bsp.standalone.sending;
导入com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
导入com.amazonaws.services.simpleemail.model.*;
导入com.amazonaws.services.sqs.AmazonSQS;
导入com.amazonaws.services.sqs.model.DeleteMessageRequest;
导入com.amazonaws.services.sqs.model.ReceiveMessageRequest;
导入com.amazonaws.services.sqs.model.ReceiveMessageResult;
导入com.amazonaws.services.sqs.model.SendMessageRequest;
导入com.googlecode.funclate.json.json;
导入java.io.PrintWriter;
导入java.io.StringWriter;
导入java.util.List;
导入java.util.Map;
公共类FromSqsEmailer实现Runnable{
私人最终AmazonSQS sqs;
私有最终字符串sendQueueUrl;
私有最终字符串deadLetterQueueUrl;
专用最终AmazonSimpleEmailService电子邮件服务;
public FromSqsEmailer(AmazonSimpleEmailService emailService、String deadLetterQueueUrl、String sendQueueUrl、AmazonSQS sqs){
this.emailService=emailService;
this.deadLetterQueueUrl=deadLetterQueueUrl;
this.sendQueueUrl=sendQueueUrl;
this.sqs=sqs;
}
公开募捐{
int batchSize=10;
整数处理;
做{
ReceiveMessageResult ReceiveMessageResult=
sqs.receiveMessage(新的ReceiveMessageRequest(sendQueueUrl).withMaxNumberOfMessages(batchSize));
最终列表toSend=receiveMessageResult.getMessages();
for(com.amazonaws.services.sqs.model.Message消息:toSend){
SendEmailResult sendResult=sendMyEmail(Json.parse(message.getBody());
if(sendResult!=null){
sqs.deleteMessage(新的DeleteMessageRequest(sendQueueUrl,message.getReceiptHandle());
}
}
numberHandled=toSend.size();
}while(numberHandled>0);
}
私有SendEmailResult sendMyEmail(映射电子邮件模型){
目的地到=新目的地()
.WithToAddress(获取(“收件人”,emailModel))
。使用ccAddress(获取(“cc”,emailModel));
试一试{
返回emailService.sendmail(新的sendmailrequest(get(“from”,emailModel),to,body(emailModel));
}捕获(例外e){
StringWriter stackTrace=新StringWriter();
e、 printStackTrace(新的PrintWriter(stackTrace));
sqs.sendMessage(新的SendMessageRequest(deadLetterQueueUrl,“发送电子邮件时”+stackTrace));
}
返回null;
}
私有字符串获取(字符串propertyName,映射emailModel){
返回emailModel.get(propertyName.toString();
}
私人邮件正文(映射电子邮件模型){
Message Message=new Message().withSubject(新内容(get(“subject”,emailModel)));
Body Body=newbody().withText(新内容(get(“Body”,emailModel)));
信息.正文(正文);
返回消息;
}
}
如果您使用的是数据库,这种方法的一个缩编是电子邮件发送步骤是HTTP调用。如果您的数据库事务在此HTTP调用后回滚,则您的业务流程将撤消,但电子邮件将被发送


值得思考。

谢谢你的详细回复,迈克。最后,我为我的应用程序实现了一个RESTAPI,使用安全的用户名+密码+密钥访问,并从第三方服务Iron.io运行它,该服务可以

www.example.com/rest/messages/format/json
它迭代并发送一个数组中收集状态的消息,然后将其发回

www.example.com/rest/messagesposted
我之所以采用这种方法,是因为我必须为超过30天的时间安排邮件 间隔90天,队列只保存消息14天左右


你发现了什么?

这个问题似乎是为亚马逊的简单队列服务量身定做的。我研究发现,SQS可以解决这个问题,但即使我将模板发送到队列,然后运行cron读取消息,发送警报,然后删除这些消息-我仍然会用该消息的发送状态更新数据库。。。当然,在数据库上保存读取数据……更重要的是,您避免了数据库服务器的持续轮询。这就是你所建议的,人们觉得很讨厌的方面。您正在用“是否有任何消息?”查询轰炸数据库。此外,您不需要“运行cron”来读取消息。您有一个作业(或多个作业,取决于工作负载)一直在运行,它可以坐在队列中并侦听队列
www.example.com/rest/messagesposted