안녕하세요 예를 들어 백엔드 서버 A -> 백엔드 서버 B와 같은 구조가 있을 때 백엔드 서버 B에 문제가 생기면 Circuitbreaker 상태가 OPEN으로 바뀔텐데 그럼 이 Circuitbreaker 상태를 OPEN으로 바꾸는건 백엔드 서버 A가 하는 건가요? 아니면 백엔드 서버 B가 하는건가요??
안녕하세요 resilience4j의 Retry는 보통 MSA 내에서 백엔드(Spring boot) 서버 <-> 백엔드(Spring boot) 서버 간의 통신에서만 사용할까요? 아니면 백엔드 서버 <-> 카프카 서버, 백엔드 서버 <-> 엘라스틱서치 서버와 같은 경우에도 자주 사용하나요?
slow call 관련 옵션 설정이 필수인 것 같은데 해당 옵션은 무시하도록 설정하는 방법이 있나요? 외부 api 호출 구간에서 500 에러가 발생할 때만 서킷 동작하게 하고 싶은데 옵션을 끄는 기능은 따로 제공이 되지 않은 것 같습니다. api 호출 시 어차피 지연되면 read time out, connection time out 등이 발생하면서 500에러를 내려 줄 거라 slow 옵션은 무시하고 싶은데 따로 방법이 있을까요? 제가 못 찾는 것일 수도 있지만 slow call exceed 이벤트가 발생할 때 일어나는 exception 이 따로 있는 것 같지 않아 ignoreException 으로 등록하는 것도 어려운 것 같습니다. 혹시 방법이 있는지 궁금합니다.
가상의 상황 외부 연동의 책임을 가진 external-interface 서버 기상청에서 제공하는 api 로부터 오늘의 날씨 를 가져올 수 있습니다. n 대로 스케일 아웃 될 수 있습니다. 현재 구성은 각 서버별로 독립적으로 서킷 브레이커를 관리하고 있습니다. ex) 기상청 api 장애 상황에서 1번 서버로 요청이 집중되어 1번 서버는 open 되었지만 2번 서버는 요청이 별로 들어오지 않아 아직 close 상태일 수 있습니다. 이 때 n 대의 서버간 서킷 브레이커의 상황을 필수적으로 공유해야 된다면 어떻게 할 것 인가? 생각하는 안 redis pub/sub 기능을 통해 구현한다. 1번 서버는 외부 연동 실패로 서킷브레이커가 open 되었다. 1번 서버는 onStateTransition 의 로직으로 open 상태를 redis 에 pub 한다. 2번 서버는 sub 하여 자신의 상태를 open 으로 동기화 한다. 하지만 우려되는 맹점이 있습니다. pub, sub 방식은 서버간 동기화의 간극이 있습니다. 결과적 일관성은 보장될지 언정 이 간극은 또 다른 이슈를 유발할 수 있습니다. ex) 1번 서버는 open 상태를 pub 했습니다. 2번 서버는 open 상태를 pub 했습니다. (1번 서버의 open 을 sub 하기 전에) 1번 서버는 close 상태가 되었지만 (외부 연동이 정상적으로 복구되었음에도 불구하고) 2번 서버에서 pub 한 open 정보에 의해 자신을 open 상태로 변경하였습니다. 동기화의 간극으로 인해 서로의 open 상태를 공유하는 것이 무한히 반복 됩니다. 물론 실제 실패로의 event 만 pub/sub 하고, redis 의 상태 공유는 pub/sub 하지 않으면 될 것 같기도 합니다. 하지만 가능/불가능 여부를 떠나 여전히 위험할 것 같다는 직감이 듭니다. redisson 과 같은 공유락까지도 생각을 해보았는데, 배보다 배꼽이 큰 것 같다는 생각이 듭니다. 그외 만약 actuator api 호출을 통해 명시적인 변경을 하고 싶다면 실무라면 대표 도메인에 elb 나 ingress 등을 설정할 것 입니다. 그러면 n 대의 서버에 상태 변경 명령을 어떻게하면 api 로 보낼 수 있나요? 혹시 이건 아예 불가능한 생각일까요? 사실 실무라면 굳이 서버간 서킷 브레이커의 상태를 공유하지 않을 것 같습니다. 장애 상황이 자주 발생하지도 않을 것이거니와 서킷 브레이커 발동을 위한 window 크기를 충분히 작게 설정한다면 회복을 방해할 정도의 트래픽이 더 들어가지는 않을 것이라고 생각하기 때문 입니다. 오히려 이런 공유 로직으로 인해 복잡도만 높아질 것이라고 생각해서 입니다. 하지만 실무를 떠나 기술적인 방법은 무엇이 있을까 인사이트가 궁금합니다.
제 프로젝트에선 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. 저는 취준생인데 이미 앞강의만 듣고도 좋은 키워드들과 방법들의 존재를 알았다는것만으로 수확을 거뒀다고 생각합니다. 뒷강의를 끝까지 듣고 제가 구현해봐도 될지.. 아니면 아직은 이런것도 있구나 하는정도 스탠스를 추천하시는지 궁금합니다.
Foo님 안녕하세요. '섹션3 - 어떤 예외를 recordExceptions로 지정할까?'를 수강하던 중 궁금증이 생겨 질문드립니다. <서론> recordExceptions은 '실패라고 간주하여 시스템을 회복시키기 위해 트래픽을 차단할 필요가 있는 상황'에 던져지는 예외로 이해했습니다. 그래서 어떤 상황에서 recordExceptions을 적용해야 할지가 매우 중요할 거라고 생각이 듭니다. 즉 트래픽을 차단할 필요가 있다면 recordExceptions을 던져야 하고 그렇지 않다면 던지지 않아야 할 것입니다. 보통은 트래픽이 많이 몰려서 예외가 발생될 때(ex OutOfMemoryError, RejectedExecutionException) recordExceptions를 적용할 거라고 생각됩니다. <본론> 그런데 트래픽이 많이 몰리지 않을 때에도 recordExceptions를 적용해야 하는 경우가 있을 것 같습니다. 한번 오류가 발생한 api 호출은 그 이후에 여러 번 호출해도 똑같은 오류가 발생될 가능성이 매우 높을 것 같기 때문입니다. (트래픽이 별로 없는 상황에서도) 그렇다면.. '모든' 외부 api 호출들에 recordExceptions를 다 적용해야 하는 건가? 라는 궁금증이 듭니다. 혹은, 생각을 반대로 전환해서, recordExceptions를 적용하지 않아도 되는 api 호출들을 구분해야 하고 나머지는 모두 recordExceptions를 적용하는 것이 맞는 건가? 라는 생각도 듭니다. 즉 어떤 기준으로 recordExceptions를 적용해야 가장 적절한 건지 궁금합니다.
IgnoreException으로 주석을 삭제하고 실행시켜볼 때 예외를 호출부로 던지는게 아니라 retry를 실행하지 않고 그냥 바로 fallback method를 실행하는데 혹시 제가 실행한 결과가 이상한걸까요? 공식문서상으로도 자세한 설명이 안보이는데 이러한 동작이 맞을까요?