• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

안녕하세요 강사님 질문있습니다!

23.12.21 19:41 작성 23.12.21 19:42 수정 조회수 158

1

제 프로젝트에선 smtp프로토콜로 gmail을 전송하고 있습니다.

앞의 강의를 몇개 듣다보니 retry로 일시적인 지연은 어느정도 해결될수있을것 같은데, 만약 gmail서버에 큰 장애가 난다면 모든 요청들이 retry회수를 꽉 채우게 되어 트래픽이 몰린다면 많은 retry가 쌓여 네트워크에 부담을 줄수있는 상황이 발생할수도 있을 것 같습니다.

(물론 개인프로젝트에서 gmail서버의 지연이나 장애까지 고려하는게 조금 너무간것 아닌가 싶기도합니다 ㅠ)

1. 위의 문제를 해결해보기위해 써킷브레이커라는 개념을 이용해 해결해볼수있다 라고 이해했는데 맞을까요?

2. 만약 위 개념을 도입하지않는다면 retry 회수를 줄이고, 아래와같이 보조(?) 메일서버를 두는것도 방법이 될수있을까요?

아니면 더 좋은방법이 어떤것들이 있는지 궁금합니다!

 

try {
    sendEmailWithSMTP();
} catch (SMTPException smtpException) {
    log.error("primary 메일서버 전송실패", smtpException);
    
    try {
        sendEmailWithNaver();
    } catch (NaverMailException naverMailException) {
        log.error("secondary 메일서버 전송실패 ", naverMailException);
        
    }
}

 

3. 저는 취준생인데 이미 앞강의만 듣고도 좋은 키워드들과 방법들의 존재를 알았다는것만으로 수확을 거뒀다고 생각합니다.

뒷강의를 끝까지 듣고 제가 구현해봐도 될지.. 아니면 아직은 이런것도 있구나 하는정도 스탠스를 추천하시는지 궁금합니다.

답변 2

·

답변을 작성해보세요.

1

scan님 오래 기다리셨습니다.

답변 하나씩 드려볼게요.

 

1. 위의 문제를 해결해보기위해 써킷브레이커라는 개념을 이용해 해결해볼수있다 라고 이해했는데 맞을까요?

-> 결론부터 이야기드리자면, 이 문제에서 서킷 브레이커가 문제 해결 방법을 간단하게 만들어 줄 수 있습니다.

다만, 오해하지 말아야 할 부분은, 서킷 브레이커는 문제 해결을 간단하게 만들어주는 도구일 뿐, 문제를 어떻게 해결할지는 개발자의 선택입니다.

우선 현재 문제 상황이 되고 있는 gmail의 장애 상황에 대해 생각해볼게요.

gmail이 장애 상황일 때 우리가 시도해볼 수 있는 방법은 어떤 것들이 있을까요? 제가 생각나는건 우선 대략 아래 정도가 있습니다. 더 있을텐데 설명을 위해 예시로 들어드린 내용에 대해서만 생각해볼게요.

 

  • gmail 대신 다른 메일 서버(or 다른 알림 수단)를 활용하여 메일을 어떻게든 전달한다.

  • 메일 전송에 실패했다고 사용자에게 알려주고 메일 보내지 않기

  • gmail이 복구될 때까지 몇번 재시도 하다가 네트워크 트래픽을 더이상 차지하지 않도록 나중에 재전송하도록 등록해두기

     

 

먼저 다른 메일 서버로 메일을 어떻게든 전달하는 경우를 생각해볼까요? 그럼 이 경우는 서킷 브레이커의 fallback을 활용하면 될겁니다. fallback으로 다른 메일 서버나 다른 알림 수단(SMS나 카톡 같은)으로 전송하도록 로직을 작성할 수 있겠죠. 이 경우 서킷 브레이커를 활용하면 문제를 간단히 해결할 수 있을겁니다. 그리고 서킷이 OPEN 되어있는 동안에는 gmail로 불필요하게 메일 전송 요청을 계속 보내지 않아도 되겠죠?

 

다음으로 메일 전송에 실패했다고 사용자에게 알려주고 메일을 보내지 않는 경우는 서킷 브레이커를 활용할 수도 있고 활용하지 않을 수도 있지만, 불필요한 트래픽을 유발하지 않기 위해서는 서킷 브레이커를 활용하는게 좋을 수 있습니다. 왜냐하면 서킷 브레이커를 활용하지 않으면 매번 gmail로 메일 전송 요청을 해볼거고, 아직 복구되지 않았을 때 역시 메일을 계속 보내게될테니까요. 금방 복구 되지 않을 상황이라면 계속 시도할 필요는 없겠죠?

 

마지막으로 gmail이 복구될 때까지 몇번 재시도하다가 네트워크 트래픽을 더이상 차지하지 않도록 나중에 재전송하도록 등록해주는 방법은 Retry와 서킷 브레이커를 동시에 사용하면 쉽게 구현할 수 있습니다. 물론 1번만 실패했을 때 나중에 재전송 하도록 하면 Retry조차 필요가 없겠죠. 아무튼 이 방법을 선택한다면, 서킷 브레이커의 fallback으로 실패한 메일 전송 정보를 DB 같은 저장소에 저장하도록 처리하면됩니다. 그럼 나중에 DB에서 데이터를 조회해와서 메일을 다시 전송하는 배치(Batch)만 추가해주면 되겠죠.

 

2. 만약 위 개념을 도입하지않는다면 retry 회수를 줄이고, 아래와같이 보조(?) 메일서버를 두는것도 방법이 될수있을까요?

-> 위 내용으로 어쩌면 이미 답변이 됐을 수도 있는데, 말씀하신 방법을 활용하는 것도 좋은 해결방법이 될 수 있습니다. 제가 메일 관련해서 전송하는 업무를 실무에서 해보진 않아서 확신에 가득차서 이야기드릴 순 없지만, 메일이 반드시 전송되어야 한다면 보조 메일 서버를 두고 해당 메일 서버로 메일을 보낼 것 같습니다. 메일 서버가 문제를 일으키는 경우는 꽤 많습니다. gmail이 장애가 나는게 아니더라도, gmail에서 scan님이 운영하는 서비스를 비정상적인 서비스라고 간주하여 메일 발송을 막아버릴 수도 있어요. 이건 실무에서도 종종 발생하는 문제입니다. 이럴때 문제가 해결되기 전까지 사용자들이 메일을 꼭 받아봐야한다면 보조 메일 서버를 지정하는게 적절한 방법이라고 생각됩니다.

3. 저는 취준생인데 이미 앞강의만 듣고도 좋은 키워드들과 방법들의 존재를 알았다는것만으로 수확을 거뒀다고 생각합니다. 뒷강의를 끝까지 듣고 제가 구현해봐도 될지.. 아니면 아직은 이런것도 있구나 하는정도 스탠스를 추천하시는지 궁금합니다.

-> 우선 강의에 대한 좋은 말씀 감사합니다. (_ _) 끝까지 들어보시고 한번 적용해보셔도 괜찮지 않을까 싶어요. ㅎㅎ 메일 말고라도 다른 곳에 적용할 수 있다면 적용해보셔도 될 것 같습니다.


마지막으로 서킷 브레이커를 도입했을 때 누릴 수 있는 효과 중 중요한 것은, 단순히 gmail 같이 외부로 가는 트래픽만 줄여주는게 아니라는겁니다. 메일 전송을 시도하는 서비스를 호출하는 또 다른 클라이언트가 있을 수 있을겁니다. 이 클라이언트는 진짜 사용자일 수도 있고, scan님이 만들어주신 또 다른 서비스일 수도 있습니다. 이 서비스가 메일 전송 서비스의 API를 호출할 때 메일 전송이 지연되면 불필요하게 latency가 발생할 수 있겠죠. 그럼 결국 이건 시스템 성능을 떨어뜨리는 결과를 가져올 수도 있습니다. 서킷 브레이커를 도입하면 문제가 되는 상황에서는 기능 실행 자체를 차단하여 전체 시스템으로 장애의 영향이 퍼지는걸 효과적으로 막고, 복구 가능한 상황에선 빠르게 복구할 수 있는 수단을 제공해준다는 것에 그 의의가 있는겁니다.

여기까지 답변이 되셨을까요? 또 궁금한 내용 있으면 질문 남겨주세요.

감사합니다.

fellow님의 프로필

fellow

질문자

2023.12.24

추가로 고민해볼만한 내용들도 같이 잘 말씀해주셔서 감사합니다ㅎㅎ 너무많은 도움이 되었습니다

0

scan님 안녕하세요~

우선 질문 해주셔서 감사합니다~

제가 현재 노트북을 쓸 수 없어서 질문 주신 내용 주말 내로 답변 드리겠습니다!

fellow님의 프로필

fellow

질문자

2023.12.21

옙 급한것 아니니까 천천히 답변주셔도 됩니다!