[비동기-2편] 비동기처리로 클라이언트 풀어주기

2025. 10. 25. 16:30·개인 프로젝트/[2025] Happy2SendingMails

 

더보기

비동기 시리즈

0편:스프링 초기세팅하기 - https://dev-dx2d2y-log.tistory.com/102 

1편:javax.mail로 메일보내기 - https://dev-dx2d2y-log.tistory.com/103

1.5편:내부클래스로 코드 간략화 - https://dev-dx2d2y-log.tistory.com/104

2편:비동기처리로 클라이언트 풀어주기

저번에 javax.mail을 통하여 메일을 보내는 코드를 작성했다.

 

메일은 정상적으로 온다.

 

그런데 소요시간을 체크해보면

거의 3~5초나 소요된다. 간단한 텍스트메일을 보내는데도 5초씩이나 걸리는 메일서비스를 누가 이용할까?

그렇기 때문에 이 소요시간을 줄일 필요가 있다.


비동기처리

그래서 등장한 것이 비동기처리

 

비동기처리는 간단히 말해서 작업을 메인스레드가 아닌 다른 스레드에 맡겨서 그 작업으로 인한 대기시간을 줄이는 처리방법이다.

근데 그러면 스레드를 하나 열어서 거기에 작업을 전달하면 되는, 아주 간단하다고 생각할 수 있지만 그렇지 않다.

 

만약 내 메일전송서비스가 아주 잘되어서 100만명이 이용한다고치자.

그러면 그 100만명의 이용자들이 모두 하나의 스레드를 열면 내 서버에는 100만 개의 스레드가 생성되게된다.

 

그러나 스레드를 여는 것부터가 프로그램 자원을 어느정도 소모하게 만들며, 지나치게 스레드를 많이열면 서버의 성능을 깎아먹는 계기가 된다. 그래서 필요한 것이 스레드 풀

 

지나친 스레드에 대한 문제를 정리한 글이 있는데 참고하면 좋을 듯하다. 아직 스레드에 대한 지식이 부족해서 이해하기 어려운데 스레드 공부 좀 하고 다시 읽으면 좀 낫지 않을까?

https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-Is-more-threads-always-better

 

🤔 스레드를 많이 쓸수록 항상 성능이 좋아질까?

스레드를 많이 쓰면 쓸수록 성능이 높아지는가 프로세스와 스레드를 처음 학습할때, 스레드는 프로세스 내에 존재하는 실행 단위이며, 이 스레드가 여러개인 덕분에 우리가 음악을 들으며 웹서

inpa.tistory.com

 


출처 : https://www.baeldung.com/thread-pool-java-and-guava / 문제 시 삭제

DB 설계할 때 DB 풀이 있는 것처럼 스레드 풀은 여러 개의 스레드를 만들어 둔 후 작업이 들어오면 각각의 스레드에 작업을 할당한다. 스레드보다 작업이 많으면 작업은 스레드가 빌 때까지 대기하게되며, 이 스레드들을 묶어 스레드 풀이라고 한다. 대표적인 스레드 풀에 대한 것이 Executor.

 

package com.ums.h2sm.Mail;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
class MailFilter {
    @Value("${spring.data.password}")
    private String password;

    void sendMailFilter(MailContentDTO mailContentDTO) throws MessagingException {
        long before = System.currentTimeMillis();

        ExecutorService executorService = Executors.newFixedThreadPool(5);
        executorService.submit(() -> {
            try {
                MailSender.sendMail(password,mailContentDTO);
            } catch (MessagingException e) {
                throw new RuntimeException(e);
            }
        });

        long after = System.currentTimeMillis();
        System.out.println("소요시간(비동기처리) : " + (after - before));

        //MailSender.sendMail(password, mailContentDTO);
    }



    private static class MailSender {
        private static void sendMail(String password, MailContentDTO contents)
                throws MessagingException, AddressException {
            System.out.println("시작");
            long before = System.currentTimeMillis();
            String user = "hongchelin422@gmail.com";

            if (password == null) {
                throw new NullPointerException();
            }

            String title = contents.getTitle();
            String content = contents.getContent();
            String address = contents.getEmailAddress();

            Properties properties = new Properties();
            properties.put("mail.smtp.host", "smtp.gmail.com");
            properties.put("mail.smtp.port", "587");
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.starttls.enable", "true");

            Session session = Session.getInstance(properties, new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(user, password);
                }
            });

            MimeMessage message = new MimeMessage(session);
            try {
                message.setFrom(new InternetAddress(user));
                message.addRecipient(Message.RecipientType.TO, new InternetAddress((address)));
                message.setSubject(title);
                message.setText(content);

                Transport.send(message);
                long after = System.currentTimeMillis();
                System.out.println("소요시간 : " + (-before + after));
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    }
}

코드 전문. 사실 이게 주 기능의 전부다.

ExecutorSerivce와 관련된 코드들이 새로 추가된 코드, 그 밑에 주석처리된 static 내부클래스를 불러오는 코드가 기존 코드다.

 

결과

소요시간(비동기처리)가 비동기처리를 보내기 직전과 직후 시간을 재서 소요시간을 나타낸 것이고, 소요시간은 메일을 보내는데 실제로 걸린 시간이다.

 

즉, 기존 코드로는 메일을 보내는 4초 간의 시간동안 클라이언트가 메일 보내는 창에 잡혀있어야했지만 비동기처리를 통해 보내는 것까지만 확인하고 다른 작업을 수행할 수 있는 것이다.

 

이렇게 보내면

 

이렇게 메일이 온다. (물론 좀 기다려야하지만)

 

실제로 네이버메일을 전송해도 약 4~5초 간의 딜레이가 있고 메일이 없는 이메일 주소로 전송되거나 하는등 잘못 전달된 경우에도 이를 알 수 없는 것으로 미루어보아 아마 비동기처리가 메일전송에 사용되고 있다고 추측할 수 있다.

'개인 프로젝트 > [2025] Happy2SendingMails' 카테고리의 다른 글

[비동기-1.5편]내부클래스 사용해보기  (0) 2025.10.22
[비동기-1편] javax.mail로 메일보내기  (0) 2025.10.21
'개인 프로젝트/[2025] Happy2SendingMails' 카테고리의 다른 글
  • [비동기-1.5편]내부클래스 사용해보기
  • [비동기-1편] javax.mail로 메일보내기
Radiata
Radiata
개발을 합니다.
  • Radiata
    DDD
    Radiata
  • 전체
    오늘
    어제
    • 분류 전체보기 (211)
      • 신년사 (3)
        • 2025년 (2)
        • 2026년 (1)
      • CS (59)
        • JVM (12)
        • 백엔드 (20)
        • 언어구현 (1)
        • 객체지향 (1)
        • 논리회로 (5)
        • 컴퓨터구조 (9)
        • 데이터베이스 (1)
        • 컴퓨터 네트워크 (10)
      • 언어공부 (64)
        • Java | Kotlin (48)
        • JavaScript | TypeScript (9)
        • C | C++ (6)
      • 개인 프로젝트 (11)
        • [2025] Happy2SendingMails (3)
        • [2026] 골든리포트! (8)
        • [2026] 순수자바로 개발하기 (0)
        • 기타 이것저것 (0)
      • 팀 프로젝트 (29)
        • [2025][GDG]홍대 맛집 아카이빙 프로젝트 (29)
      • 알고리즘 (13)
        • 백준풀이기록 (11)
      • 놀이터 (0)
      • 에러 수정일지 (2)
      • 고찰 (24)
        • CEOS 23기 회고록 (2)
  • 블로그 메뉴

    • CS
    • 언어공부
    • 개인 프로젝트
    • 팀 프로젝트
    • 알고리즘
    • 고찰
    • 신년사
    • 컬러잇 개발블로그
  • 링크

    • 컬러잇 개발블로그
  • 공지사항

  • 인기 글

  • 태그

    144
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Radiata
[비동기-2편] 비동기처리로 클라이언트 풀어주기
상단으로

티스토리툴바