✏️ 외부 연동
타임아웃
서비스를 호출할 때 타임아웃을 적절히 설치를 해야합니다.
타임아웃 설정을 안했을 경우
- A서비스에서 커넥션 풀 크기가 200입니다.
- A서비스에서 B서비스를 호출
- B서비스 문제가 생겨서 응답시간이 60초를 넘김
- 100명의 사용자가 서비스 호출
- 응답 대기
- 사용자 재요청 및 다른 인원 추가 호출
- 무한 대기
- 상태가 이어질 경우 서버 마비
연결 타임아웃
API 통신 연결 → 요청 → 응답 → 종료 순 입니다.
네트워크 연결 시도 단계
- 연결은 상황에 따라 오래걸릴 수 있습니다.
- 걸리는 시간에 따라 대기 시간도 증가합니다.
- 대기 시간이 증가함에 따라 성능 문제도 발생합니다.
- 3 ~5초 설정 추천
결론 : 연결 대기시간 제한이 필요합니다. → 연결 타임아웃
↔ 비슷한 상황으로는
읽기 타임아웃
연결 → 요청 → 응답에서 응답을 받기까지 시간이 오래걸리면 같은 문제가 발생
- 5 ~ 30초 설정 추천
- 1 ~ 3초 정도로 짧게 설정하면 타임아웃 에러 자주 발생
- 간헐적으로 연동시간이 길어지더라도 정상적으로 처리할 수 있어야 합니다.
재시도
외부 연동에 실패했을 때 처리 방법 중 하나
- 네트워크 통신 과정에서 간헐적으로 연결에 실패 or 일시적 응답 느려지는 경우
- 재시도를 통해 연동 실패를 성공으로 바꿀 수 있습니다.
재시도 가능 조건
연동 API를 다시 호출해도 되는 조건인지 확인
단순 조회 기능
- 데이터 문제가 없는 조회 기능을 다시 처리해줍니다.
연결 타임아웃
- 네트워크 문제로 인한 연결되지 않은 상태의 문제를 해결해줍니다.
멱등성을 가진 변경 기능
- 멱등성 : 연산을 여러번 적용해도 결과가 달라지지 않는 성질
- 동일한 API를 읽기 요청을 할 경우
- 처음일 경우는 추가가 되도록 해줌
- 처음이 아닐경우 데이터의 값이 중복처리 되지 않고
결론 : 같은 API라도 실패 원인에 따라 재시도 여부를 결정
- 검증 오류가 발생할 경우 재시도를 해도 동일하게 실패할 가능성이 높음
재시도 횟수와 간격
재시도 횟수
- 무한정 x
- 대부분의 경우 : 1~2번 재시도
- 그 이상은 다시 재시도해도 실패할 확률이 높다
재시도 간격
- 여러 차례 재시도할 때는 재시도 간격을 점진적으로 늘림
재시도 폭풍 안티패턴
재시도는 연동 서비스에 더 큰 부하를 줄 수 있음
- 연동 서비스의 성능이 느려져서 읽기 타임아웃이 발생한 상황
- 재시도를 하면 같은 요청이 두배로 받음
- 성능이 낮아짐
연동 서비스의 성능 상황도 고려대상
동시 요청 제한
연동 서비스의 최대 처리량을 초과하여 응답 시간이 느려질 수 있습니다.
- 연동 서비스의 한계를 초과해서 요청을 보내면, 연동 서비스의 응답 시간이 느려지면서 전반적인 성능이 저하될 수 있습니다.
- 연동 서비스의 성능 한계를 초과하지 않는 수준에서 요청을 보냄으로써 전체적으로 응답 시간이 느려지는 문제를 완화할 수 있습니다.
벌크헤드 : 각 구성 요소를 격리함으써 한 구성 요소의 장애가 다른 구성 요소에 영향을 주지 않도록 설계 패턴
서킷 브레이커
과도한 오류가 발생하면 연동을 중지시키고 바로 에러를 응답한다. 연동 서비스로의 요청 전달을 차단할 수 있습니다.
닫힘
- 모든 요청을 연동 서비스에 전달한다.
- 외부 연동 과정에서 오류가 발생하기 시작하면, 지정한 임계치를 초과했는지 확인한다.
열림
- 실패 건수가 임계치를 초과하면 서킷 브레이커는 열림 상태가 된다.
- 연동 요청은 수행하지 안혹, 바로 에러 응답을 리턴한다.
- 지정된 시간 동안 유지된다.
반 열림
- 일부 요청에 한해 연동을 시도한다.
- 일정 개수 또는 일정 시간 동안 반 열림 상태를 유지하며, 이 기간 동안 연동에 성공하면 닫힘 상태로 복귀한다.
- 연동에 실패하면 다시 열림 상태로 전환되어 연동을 차단한다.
빠른 실패 : 실패를 빠르게 감지하고, 문제가 있는 기능을 실행하지 않고 중단시키는 방식
장애가 발생한 기능에 부하가 더해지는 것을 방지할 뿐 아니라, 불필요한 자원 낭비를 줄여 전체 서비스의 안전성을 유지하는 데도 도움이 된다.
외부 연동과 DB 연동
DB에 데이터를 저장하는 과정에서 실패할 수도 있고, 외부 서비스를 연동하는 도중에 에러가 발생할 수도 있습니다.
외부 연동과 트랜잭션 처리
외부 연동에 실패했을 때 트랜잭션을 롤백
외부 연동에 실패했을 때 트랜잭션을 롤백
- 롤백을 통해 DB 데이터에 이상이 생기는 것을 방지
- 읽기 타임아웃 발생 해 트랜잭션을 롤백할 때는 외부 서비스가 실제로는 성공적으로 처리했을 가능성 염두
외부 연동은 성공했지만 DB 연동에 실패해 트랜잭션을 롤백
- 일정 주기로 두 시스템의 데이터가 일치하는지 확인하고 보정하는 방법
- 성공 확인 API를 호출하는 방식
외부 연동은 성공했는데 DB 연동에 실패해서 트랜잭션을 롤백
- DB 연동에 실패했기 때문에 성공 확인 API를 호출해도 의미가 없음
- 일정 주기로 데이터가 맞는지 비교하는 프로세스가 필요
외부 연동이 느려질 때 DB 커넥션 풀 문제
- 커넥션 풀에서 커넥션을 가져온다.
- 0.1초 걸리는 DB 쿼리를 실행한다
- 외북 연동 API를 호출(API 실행에 4.8초 소요)한다.
- 0.1초 걸리는 DB 쿼리를 실행한다.
- 커넥션을 풀에 반환한다.
- 외부 연동에 4.8초가 걸려서 최종 5초가 소요되는 API입니다.
DB 커넥션을 사용하기 전이나 후에 외부 연동을 시도하는 방안 고려
- DB 커넥션 풀이 포화되는 상황을 방지
- 트랜잭션 커밋 이후 외부 연동이 실패하면 롤백이 불가능
- 후처리를 반드시 고민
- 보상 트랜잭션을 사용하는 방법
- 기능 특성에 따라 데이터를 후보정하는 방법
HTTP 커넥션 풀
HTTP 연결도 커넥션 풀을 사용하면 연결 시간을 줄일 수 있어 응답 속도 향상에 도움이 된다.
HTTP 커넥션 풀의 크기
- 커넥션 풀 크기를 너무 늘리면
- 트래픽이 몰릴 때 연동 서비스의 응답 시간이 급격히 느려질 수 있음
- 성능 저하가 전체 서비스 성능 저하가 될 수 있음
풀에서 HTTP 커넥션을 가져올 때까지 대기하는 시간
- 대기 시간이 길어지면
- 전체 응답 시간도 함께 늘어남
- 대기 시간은 수 초이내 짧은 시간으로 설정하는게 좋음(1~5초)
HTTP 커넥션을 유지할 시간
- 커넥션은 무한정 유지되지 않는다
- 커넥션을 유지한 뒤 연결을 끊는 경우도 있음
연동 서비스 이중화
서비스가 대량 트래픽을 처리할 만큼 성장했다면 연동 서비스의 이중화를 고려해야 한다.
- 한 곳에 장애가 발생해도 다른 결제 서비스를 이용해 결제가능
- 이중화하는 만큼 개발과 유지에 드는 비용도 증가
고려해야 할 사항
- 해당 기능이 서비스의 핵심인지 여부
- 이중화 비용이 감당 가능한 수준인지
자료 출처
https://product.kyobobook.co.kr/detail/S000216376461