- 마이스로서비스 환경이 도입 되면서 내부든 외부든 서비스간 연동이 보편화 되고 복잡해지고 있음
- 이때 외부 서비스에서 장애가 발생하면 외부 서비스를 호출하는 내부 서비스에도 장애가 전파될 수 있음
- 이 장에서는 이런 서비스 연동시 발생할 수 있는 장애를 최소화하는 방법을 살펴봄
타임아웃
- 2가지의 타입아웃
- 연결 타임아웃: 3초 ~ 5초
- 읽기 타임아웃: 5초 ~ 30초
재시도
- 연동 실패시 다시 시도하는것
- 재시도 가능 조건
- 무조건 재시도 가능한건 아님
- 예를 들어 포인트 차감 등의 API를 재시도하면 중복 차감이 발생할 수 있음
- 위 2가지 타임아웃중 읽기 타임아웃에 해당
- 보통 다음 상황시 재시도 가능
- 단순 조회 기능
- 연결 타임아웃
- 멱등성(idempotent)을 가진 변경 기능
- 재시도 횟수와 간격
- 재시도시에는 다음 2가지를 결정해야함
- 무한정 재시도를 할 수는 없음
- 네트워크 장애 등으로 일시적으로 실패할 수 있음
- 몇 번의 시도로 위 상황에 대한 대처가능
- 서버 자체가 문제인경우 계속된 재시도는 무의미
- 재시도 폭풍(retry storm) 안티패턴
- 연동된 서버에서 부하로 인한 장애가 발생한 경우 계속된 재시도는 장애를 악화시킬 수 있음
- 따라서 재시도는 연동 서비스의 성능 상황도 함께 고려해야함
동시 요청 제한
- 연동 서비스 최대 동시 요청수가 100일때 300개의 요청을 보내면 응답 시간에 문제가 발생, 이는 우리 서비스에도 영향을 미침
- 특히 선착순 이벤트 등과 같은 트래픽이 몰릴때 발생 가능
- 벌크헤드(Bulkhead)
- 동시 요청수를 제한하는 방법
- 연동서비스가 최대 100개의 요청을 처리할수 있으면 300개의 요청이 들어올때 100개만 보내고 나머지 200개는 실패처리
서킷 브레이커
- 서킷 브레이커의 상태
- 닫힘(Closed)
- 열림(Open)
- 반 열림(Half-Open)
- 빠른 실패
외부 연동과 DB연동
- 외부 연동과 트랜잭션 처리
- 외부 연동과 DB연동을 함께 처리할때 트랜잭션 처리를 어떻게 할지 고민
- 외부 연동에 실패했을때 트랜잭션 롤백
- 외부 연동이 실패해 트랜잭션을 롤백하는 경우 DB 데이터에 이상이 생기는것을 방지할 수 있음
- 그러나 타임아웃이 발생해서 트랜잭션을 롤백하는 경우, 외부 서비스가 실제로는 성공적으로 처리했을 가능성을 염두해야함
- 이때는 2가지 방법이 있음
- 일정 주기로 두 시스템의 데이터가 일치하는지 확인하고 보정
- 일정 시간후 성공 확인 API를 호출
- 외부 서비스에서 성공 확인 API를 지원할때만 사용가능
- 두 시스템간 일관성을 정기적으로 확인하는 프로세스를 갖추는 것이 바람직함
- 외부 연동은 성공했지만 DB 연동에 실패 트랜잭션을 롤백
- 외부 연동은 성공했지만 DB 연동에 실패한경우 취소 API를 호출해서 이전 상태로 되돌리는것이 필요
- 이 경우도 두 시스템간 일관성을 정기적으로 확인하는 프로세스를 갖추는 것이 바람직함
- 외부 연동이 느려질 때 DB 커넥션 풀 문제
- 외부 연동이 느려지면 DB 커넥션 풀이 고갈될 수 있음
- DB 연동과 무관하게 외부 연동을 실행해서 커넥션 풀 포화 상황을 방지 가능
- 단 외부연동 실패시 트랜잭션 롤백 불가능
- 이때문에 후처리 고민필요, 보상 트랜잭션 등을 사용하는 방법이 존재
HTTP 커넥션 풀
연동 서비스 이중화
- 서비스가 성장해서 트래픽이 많아지면 이중화를 고려해야함
- 2가지를 고려해야함
- 해당 기능이 서비스의 핵심인지
- 이중화 비용이 감당 가능한 수준인지