Post

[playkuround] 이메일 비동기 처리 및 템플릿 적용

Intro

어느덧 플레이쿠라운드가 출시된지 3주가 되어갑니다. 정말 많은 학우분들의 관심을 받은 것 같습니다.

내일(20일)은 플레이쿠라운드 팀에서 준비한 오프라인 행사가 기획되어 있습니다. SNS 팔로우 또는 앱 다운로드를 하면 뽑기를 통해 띠부씰을 받을 수 있어요.
인스타그램 게시물 보기
빅(?)이벤트를 대비하여 인증 메일을 개선했습니다.

이메일 비동기 처리

기존에는 이메일 전송이 동기화로 작업 됐습니다. HTTP 요청을 받은 서버는 이메일 전송이 완료(또는 실패)되어야지 response를 클라이언트에게 보내줍니다. 이메일이 전송되는 동안 앱에서는 빙글빙글 로딩 화면만 봐야 했습니다. 좋지 못한 사용자 경험입니다.

출시 전 QA 기간 때 앱에서 이메일 전송 에러가 간헐적으로 발생했었습니다. 서버로부터 응답 시간이 너무 길어져서 발생한 문제였어요. (다른 처리할 일이 많았기에) 일단은 앱단에서 API 타임아웃 시간을 늘려서 해결했었습니다.

서버가 미안해

스프링은 기본적으로 톰켓의 쓰레드 풀에서 쓰레드를 할당받아 request를 처리합니다. 할당받은 쓰레드는 해당 요청을 전담하여 모든 처리를 진행합니다. 많은 사용자가 한 번에 인증 메일 전송을 요청하면 어떻게 될까요? 아마 쓰레드 풀의 쓰레드를 모두 사용해서 서비스 속도가 매우 느려질 것입니다.

https://netal.tistory.com/entry/Spring-서버-성능테스트와-톰캣-쓰레드Thread-확장

스프링에서는 비동기 처리를 위한 @Async 애노테이션을 지원합니다. 해당 애노테이션은 스프링 AOP에 의해 프록시 패턴을 기반으로 동작합니다. 또한 AsyncConfigurer을 구현하여 비동기 쓰레드 풀을 설정할 수 있습니다. 해당 코드 관련해서는 다른 많은 블로그 포스팅이 있으니 참고 바랍니다.

비동기 처리를 통해서 기존에는 3.1s 걸리던 요청을 167ms로 18.5배 개선했습니다.

이메일 전송이 실패하면 어떻게 되나요? 음.. 별다른 조치를 하지 못합니다. 서버에서 로그 정보는 남길 수 있겠네요. 많은 서비스에서는 사용자가 수동으로 재전송 버튼을 클릭하도록 만들었습니다.
메일 서버가 다운 상태면 어쩌죠? 저희는 현재 구글 이메일을 사용하고 있습니다. 외부 서비스를 의존하는 순간 에러 핸들링을 잘 처리해야 합니다. 이 부분에 관해서는 더 공부해서 포스팅하도록 하겠습니다
(우리 서비스가 먼저 죽을까, 구글 서비스가 먼저 죽을까)

메일 템플릿 적용

기존에는 딱딱한 글씨만 존재하는 메일이 전송됐었습니다.

앱 설치 후 회원가입(또는 로그인)을 위해서 메일 인증을 하게 됩니다. 처음 시작하는 유저분들이 기대되는 마음을 갖게 하도록 인증 메일을 꾸몄습니다.

템플릿으로는 thymleaf를 사용했습니다. 먼저 TemplateEngine을 주입받습니다.
타임리프는 기본적으로 resources/templates 디렉터리를 서칭하게 설정되어 있습니다. 따라서 해당 디렉터리에 타임리프 파일을 넣어주면 됩니다. 타임리프 변수에 값을 넣기 위해 context를 사용할 수 있습니다. 아래 코드를 보시면 한 번에 이해가 되실 거예요.

1
2
3
Context context = new Context();
context.setVariable("code", authenticationCode);
String content = templateEngine.process("mail-template", context);

한 가지 중요한 이슈는 저의 프론트 실력입니다. 열심히 땅을 파며, (제 눈에는 이쁜) 웹 프론트를 만들었습니다. 이쁘죠?(강요)

사용자분들이 설렘을 갖고 시작할 수 있도록 귀여운 덕쿠 캐릭터도 넣었어요.

Outro

플레이쿠라운드 첫 오프라인 행사 준비를 마쳤습니다.
기존의 서버로도 충분히 트래픽을 받을 수 있을 것 같아, scale out, up은 따로 하지 않았습니다.
하지만 당일 열심히 모니터링하며 바로 대응할 수 있도록 준비할 예정입니다.
다음 게시물은 행사 후기로 돌아오겠습니다!

This post is licensed under CC BY 4.0 by the author.