[교내 공지사항 알림 서비스] 개발일기 4편 [Gmail 발송제한 완화법]

이번 글에서는 메일 발송제한을 좀더 완화하기 위해 생각해낸 방법을 소개하겠다!

 

내가 만든 알림 서비스 구조에서 메일 발송을 하는 행동은 다음과 같다.

 

1. 사용자가 이메일 인증을 통해 구독을한다.

2. 사용자가 이메일 인증을 통해 구독을 취소한다.

3. 하루에 한번 당일 공지사항을 전달받는다.

 

사실상 1, 2번은 한세트이기 때문에 2개로 나뉜다. 

때문에 Google 계정을 하나 더 만들어서 한 계정은 인증메일만 보내고 다른계정은 공지사항을 발송하는 역할을 맡게 하였다.

 

처음엔 2개의 메일 계정을 통해 메일 발송하는게 가능할지 확실치 않았는데 ChatGPT 선생님께서 좋은 방법을 제안해주셨다.

spring:
  mail:
    verification:
      host: smtp.gmail.com
      port: 587
      default-encoding: UTF-8
      username: 
      password: 
      properties:
        mail:
          smtp:
            auth: true
            starttls:
              enable: true
              require: true
    notice:
      host: smtp.gmail.com
      port: 587
      default-encoding: UTF-8
      username: 
      password: 
      properties:
        mail:
          smtp:
            auth: true
            starttls:
              enable: true
              require: true

 

이런식으로 yaml 파일을 써주면 각각 사용 가능하다. 왜냐면 SpringFramework 에서 지원하는 @Value 어노테이션을 이용해 값을 가져다 쓰면 되기때문이다.

 

JavaMailSender를 다음과같이 2개 만들어서 Bean으로 등록하면 가져다 쓸 수 있게된다.

@Configuration
public class MailConfig {

    @Bean(name = "verificationMailSender")
    public JavaMailSender verificationMailSender(
        @Value("${spring.mail.verification.host}") String host,
        @Value("${spring.mail.verification.port}") int port,
        @Value("${spring.mail.verification.username}") String username,
        @Value("${spring.mail.verification.password}") String password,
        @Value("${spring.mail.verification.default-encoding}") String encoding,
        @Value("${spring.mail.verification.properties.mail.smtp.auth}") boolean auth,
        @Value("${spring.mail.verification.properties.mail.smtp.starttls.enable}") boolean starttlsEnable,
        @Value("${spring.mail.verification.properties.mail.smtp.starttls.require}") boolean starttlsRequire
    ) {
        return createMailSender(host, port, username, password, encoding, auth, starttlsEnable, starttlsRequire);
    }

    @Bean(name = "noticeMailSender")
    public JavaMailSender noticeMailSender(
        @Value("${spring.mail.notice.host}") String host,
        @Value("${spring.mail.notice.port}") int port,
        @Value("${spring.mail.notice.username}") String username,
        @Value("${spring.mail.notice.password}") String password,
        @Value("${spring.mail.notice.default-encoding}") String encoding,
        @Value("${spring.mail.notice.properties.mail.smtp.auth}") boolean auth,
        @Value("${spring.mail.notice.properties.mail.smtp.starttls.enable}") boolean starttlsEnable,
        @Value("${spring.mail.notice.properties.mail.smtp.starttls.require}") boolean starttlsRequire
    ) {
        return createMailSender(host, port, username, password, encoding, auth, starttlsEnable, starttlsRequire);
    }

    private JavaMailSender createMailSender(String host, int port, String username, String password, String encoding,
        boolean auth, boolean starttlsEnable, boolean starttlsRequire) {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(host);
        mailSender.setPort(port);
        mailSender.setUsername(username);
        mailSender.setPassword(password);
        mailSender.setDefaultEncoding(encoding);

        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", auth);
        props.put("mail.smtp.starttls.enable", starttlsEnable);
        props.put("mail.smtp.starttls.required", starttlsRequire);
        props.put("mail.debug", "false");

        return mailSender;
    }
}

 

이러한 방식으로 2개의 메일 계정으로 부하를 분산하였다. 이것도 로드 밸런싱 했다 라고 말할 수 있을 것 같다 ㅋㅋ

하지만 구독자가 500명이 넘게되면 무료 계정으로는 불가능하다는 제한이 아직까지 있다. 

찾아보니까 Google WorkSpace 계정을 만들면 더 많은 메일을 보낼 수 있다는 것 같은데 가격이 꽤 비싸서 고려대상이 아니다.