有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java提高了通过springmail发送批量电子邮件的性能

我有一个spring独立应用程序,它使用简单的spring电子邮件代码,如下所示,tomessage是使用map中迭代的值构造的

我已经对问题here提出了一些建议,但我需要一些具体的建议。下面是我的代码

for (Map.Entry<String, List<values>> entry : testMap
                .entrySet()) {
            String key = entry.getKey();
            StringBuilder htmlBuilder = new StringBuilder();            
            List<Model> valueList = entry.getValue();
            for (Model value : valueList) {
                htmlBuilder.append('List Values in the message');
            }
            mail.sendMail( msgFrom,body); // call my sendMail function in another class
        } 

发送邮件的代码:

        MimeMessage email = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(email, true);
        helper.setFrom(new InternetAddress(from));
        helper.setTo(new InternetAddress(to));
        helper.setText(msg, true);
        helper.addInline("identifier1234", res);
        mailSender.send(email);

发送邮件需要3到4秒钟。我每天有大约40万的用户列表要发送

我是否做错了什么,或者采取了其他方法来加快这个过程。我需要专家的建议

感谢您的时间和帮助:)


共 (3) 个答案

  1. # 1 楼答案

    您可以将sendMail封装到单独的可运行类中,并将任务放入ExecutorService(或者在sendMail方法之上使用@Async,但这很难配置——这只是我的观点)

  2. # 3 楼答案

    依我看,发送邮件本身的过程可以得到改进,因为目前,每封邮件都会打开一个到邮件服务器的新连接。您可以通过使用批处理发送来改进它

    Spring MailSender接口本机支持发送一组消息,而不是单个消息,因此您不必明确地处理JavaMail会话。你可以简单地修改这个类实际上是通过这种方式发送邮件的

    int batchSize = 16; // for example, adjust it to you needs
    MimeMessage[] messages = new MimeMessage[batchSize];
    int messageIndex = 0;
    
    public void sendMail(String msgFrom, String body) {
        // prepare MimeMessage
        messages[messageIndex++] = email;
        if (messagesIndex == batchSize) {
            mailSender.send(messages);
            messageIndex = 0;
        }
    
    public void sendLastMails() {
        if (messageIndex > 0) {
            MimeMessage[] lastMessages = new MimeMessage[messageIndex];
            for (int i =0; i<messageIndex; i++) {
                lastMessages[i] = messages[i];
        }
        mailSender.send(lastMessages);
    }
    

    编辑:

    可以在多个地方调用sendLastMails方法。首先,必须在单例bean的destroy方法中调用它,以确保应用程序关闭时不会忘记任何消息。如果发送邮件的类是单例bean,那么声明bean的destroy方法是sendLastMail,或者调用它就足够了

    然后,根据您自己的业务规则,它可能会在发送邮件后调用。典型用法:在你的例子中,你有testMap。你应该这样重写:

        for (Map.Entry<String, List<values>> entry : testMap
                .entrySet()) {
            ...
            mail.sendMail( msgFrom,body); // call my sendMail function in another class
        }
        mail.sendLastMails();
    

    现在由你来决定,这一改进是否足够,或者你是否应该外包