복붙노트

[SPRING] 스프링 메일을 통해 대량 전자 메일을 보내는 성능 향상

SPRING

스프링 메일을 통해 대량 전자 메일을 보내는 성능 향상

아래의 간단한 봄 이메일 코드를 사용하는 스프링 - 스탠드 (spring-stand) 혼자의 애플리케이션을 가지고 있습니다. to와 메시지는 맵에서 반복 된 값을 사용하여 생성됩니다.

나는이 질문에 대해 이미 몇 가지 제안을했지만, 이에 대한 구체적인 조언이 필요하다. 아래 코드는

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 만 명의 대규모 사용자 목록을 보내고있다.

나는이 과정을 고정시키기 위해 잘못되었거나 다른 어떤 방법을 사용하고 있습니까? 나는 전문가의 도움이 필요하다.

시간과 도움을 주셔서 감사합니다 :)

해결법

  1. ==============================

    1.IMHO, 현재 메일 당 메일 서버에 대한 새 연결을 열기 때문에 메일 자체를 보내는 프로세스를 향상시킬 수 있습니다. 일괄 송신을 사용하여 성능을 향상시킬 수 있습니다.

    IMHO, 현재 메일 당 메일 서버에 대한 새 연결을 열기 때문에 메일 자체를 보내는 프로세스를 향상시킬 수 있습니다. 일괄 송신을 사용하여 성능을 향상시킬 수 있습니다.

    Spring MailSender 인터페이스는 기본적으로 하나의 메시지 배열 대신에 메시지 배열을 지원하므로 JavaMail Session을 명시 적으로 처리하지 않아도됩니다. 실제로 메일을 보내는 클래스를 수정하면됩니다.

    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 메소드는 여러 위치에서 호출 될 수 있습니다. 첫째, 애플리케이션이 닫힐 때 메시지를 잊어 버리지 않도록 싱글 톤 빈의 destroy 메소드에서 호출되어야합니다. 메일을 보내는 클래스가 싱글 톤 빈인 경우 빈에 대한 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();
    

    이 개선이 충분한 지 아니면 아웃소싱해야하는지 이제는 당신에게 달려 있습니다.

  2. ==============================

    2.기본적으로 대답은 직접하지 않는 것입니다.

    기본적으로 대답은 직접하지 않는 것입니다.

    아주 상세한 이유는 다음과 같습니다. 매주 10 만 개의 이메일을 보내는 방법은 무엇입니까?

  3. ==============================

    3.sendMail을 별도의 Runnable 클래스로 묶고 ExecutorService에 작업을 넣을 수 있습니다 (또는 sendMail 메서드 위에 @Async를 사용하지만 구성하기가 어렵습니다).

    sendMail을 별도의 Runnable 클래스로 묶고 ExecutorService에 작업을 넣을 수 있습니다 (또는 sendMail 메서드 위에 @Async를 사용하지만 구성하기가 어렵습니다).

  4. from https://stackoverflow.com/questions/26231165/improve-performance-on-sending-bulk-emails-through-spring-mail by cc-by-sa and MIT license