1

I have a spring-stand alone application which uses simple spring email code as below , the to and the message is constructed using the values iterated from map.

I have already had some suggestions for the question here , but i am in need of some specific advise for this. below is my code

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
        } 

Code for sending mail :

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

It takes 3 to 4 seconds to send mail . I have large user list of around 400,000 each day to be sent

Am i doing anything wrong or anyother approach to fasten this process. I am in need of experts advise

Thanks for your time and help :)

Community
  • 1
  • 1
Santhosh
  • 8,181
  • 4
  • 29
  • 56
  • sorry cant get what you are saying – Santhosh Oct 07 '14 at 12:32
  • The internet gets a bad name because of flooding with unwanted emails. I wish I could set it up so that everyone who wanted to send me a message would have to pay me an amount I choose, like 5 cents. That would stop a lot of spam in its tracks. – Mike Dunlavey Oct 07 '14 at 13:06
  • 1
    Actually its scenario of notifying the bill dates . wont you like if you get a reminder when you forgot a bill payment. And i am going to use a dedicated server for it – Santhosh Oct 07 '14 at 13:11
  • That's a good usage - sorry - you hit my flame button. – Mike Dunlavey Oct 07 '14 at 13:13

3 Answers3

4

IMHO, the process of sending mail itself can be improved, because currently, you open an new connection to mail server per message. You could improve it by using batched sending.

Spring MailSender interface natively supports sending of an array of messages instead of a single one, so you do not have do explicitely deal with JavaMail Session. You could simply modifiy the class actually sending the mail that way

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

Edit:

The sendLastMails method may be called in several places. First, it must be called in the destroy method of a singleton bean to make sure no messages are forgotten when application closes. If the class sending mail is a singleton bean, it is enough to declare that the destroy method for the bean is sendLastMail, or calls it.

Then depending on you own business rules, it may be called after a batch of mails have been sent. Typical usage : in you example, you have testMap. You should rewrite it that way :

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

Now it is up to you to see if this improvement is enough or if you should outsource.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
2

Basically the answer is to not do this yourself.

Here is a very detailed reason why not: How to send 100,000 emails weekly?

Community
  • 1
  • 1
weston
  • 54,145
  • 21
  • 145
  • 203
  • so the best way is to outsource the job ? – Santhosh Oct 07 '14 at 08:52
  • Yes outsourcing is the answer. – weston Oct 07 '14 at 08:57
  • no other go ? i am ready use a kind of batch jobs even with other frameworks of Java – Santhosh Oct 07 '14 at 08:58
  • It's not a problem that can be resolved with a framework as many of the issues listed in that very highly respected post involve other servers outside your control. Why are you against outsourcing? It'll save you time and money in the long run. – weston Oct 07 '14 at 12:50
1

You can enclose sendMail into separate Runnable class and put tasks into ExecutorService ( or use @Async above sendMail method, but this is harded to configure - just my opinion ).

hi_my_name_is
  • 4,894
  • 3
  • 34
  • 50
  • thanks for your answer :) but i dont want get into threading concepts .. worried about their performance in jvm – Santhosh Oct 07 '14 at 10:28