7~8개월 전 일이지만 게을러서 지금에야 적는 글이다.


회사가 점점 커지고 개발팀이 점점 커지면서 미뤄두었던 숙제를 하나씩 꺼내어 처리하고 있는데 그 중 하나는 바로 이메일 전송방식 개선이다. 지금은 파트너 혹은 고객에게 이메일을 보낼 일이 있다면 API에서 직접 노드 메일러로 메일을 보내고 있었는데 사실 이렇게 하면 API의 처리량이 떨어지기 때문에 하면 안되는 안티패턴이다. 여태까지는 그렇게 요청이 많지 않았고 별 무리가 없어서 일단 나중에 해야겠다고 미뤄뒀었는데, 드디어 꺼내어 처리할 수 있게 되었다.

이메일 전송은 사실 별도의 Queue에 던져놓고 Worker가 Queue에서 빼서 보내는 방식으로 처리하는게 제일 좋은 방법이다. 클라우드를 이용한다면 AWS SES가 해당 서비스가 된다. Node.js를 쓰는 우리 시스템에서는 하나의 방법이 더 있다. Node.js의 EventEmitter를 이용해서 내부적으로 Event Queue를 통해서 처리하는 방식이다.

아키텍쳐를 구성하는 컴포넌트는 뭐든 본업에만 충실하는게 좋기 때문에 API앱은 API 서빙에만 충실하게 두고, 이메일은 AWS SES가 처리하도록 설정했다. 문제가 없었으면 이 글이 쓰이지 않았을테다. 메일 전송 시스템을 모두 SES로 변경된 후 중국 내 일부 파트너들만 이메일을 받지 못하는 일이 발생했다. 그렇다고 100% 못받는건 아니고 받다 말다 한다는데 정말 미칠 노릇이었다.

다행히 그쪽 시스템에서 날아온 반송 메일이 있었는데, 여기에는 그저 아래와 같은 내용만 있었다.

An error occurred while trying to deliver the mail to the following recipients:
aaa@aaa.com
bbb@bbb.com

혹시 해서 이메일 원본을 까서 분석해보니 다행히 단서를 찾을 수 있었다.

Diagnostic-Code: smtp; 550 Ip frequency limited http://service.exmail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000725

즉 이 회사는 QQ의 이메일 시스템을 사용하고 있었는데, QQ의 이메일 정책을 보니 550 IP 전송 빈도 제한서버 IP 의 전송 빈도가 Tencent 사서함의 제한을 초과하기 때문이었다. 즉, 내가 너무 많이 보내어 QQ측에서 발송을 제한했다는 내용이었다. 알아보니 qq.com은 각 메일서버의 IP당 정책적으로 발송량을 제한하고 있었다.

  1. 분당 최대 전송량이 정해져있으며 이를 넘길경우 몇 분간 일시차단
  2. 시간당 최대 전송량이 정해져있으며 이를 넘길경우 몇 시간 동안 일시 차단
  3. 하루 최대 전송량이 정해져있으며 이를 넘길경우 몇 일동안 차단
  4. 각 최대 전송량은 정책상 비밀로 비공개

즉 AWS SES에서 qq.com 으로 메일을 너무 많이 보내어 차단했다는 얘기가 된다. AWS SES는 여러 사용자가 같이 사용하는데 하필 여기서 qq.com 시스템으로 메일을 너무 많이 보내서 일시 차단당한 것이다. SES에서 이렇게 문제가 생긴다면 방법은 3가지였다.

  1. 공용 IP를 쓰는 SES 대신 전용(Dedicated) IP 사용(링크)
  2. 현재 노드 메일러 그대로 사용
  3. 다른 이메일 발송 서비스 사용

결론은 3번이었다. 1번을 하지 않은 이유가… 메일서버 IP마다 평판이라는 데이터가 존재한다. 이 평판을 결정짓는 요인은 해당 주소에서 얼마나 많은 양질의 이메일을 전송했는지 여부다. 그런데 새로 전용 IP를 사용한다면 평판 정보가 없기 때문에 지메일이나 QQ같은 이메일 공급자는 우리 IP로부터 오는 이메일을 무조건 스팸처리하거나 차단될 가능성이 높다. 처음부터 조금씩 보내서 평판을 높여야되는데 그러기엔 시간이 없었다.

결국 3번. PostMark를 사용하여 이메일을 보내게 되었다. MailGun도 생각해봤는데, 팀원 중에 한 명이 한 번 써보자고 해서 이를 채택했다. 이메일 발송 기록도 남고 각종 통계와 웹훅도 지원해서 지금도 만족하면서 쓰고 있다.