동기 방식은 일련의 실행 과정이 순차적으로 진행되는 것을 말한다. 즉 한 작업이 마무리되기 전까지 다른 작업이 기다려야 한다는 의미이다. 이러한 동기 방식은 호출한 함수 혹은 작업이 반환될 때까지 실행 흐름이 차단되는 특징이 있다.
비동기(Asynchronous)
비동기 방식은 작업들이 독립적으로 실행되는 것을 의미한다. 그래서 작업의 완료 여부에 상관없이 다른 작업을 실행할 수 있다. 비동기 방식은 I/O 처리나 네트워크 요청과 같이 시간이 오래 걸리는 작업에 적용하는 방식으로, 콜백, 프로미스, async/await 등으로 구현 가능하다.
그렇다면 동기 방식으로 외부 서비스를 호출 및 처리하는 서비스에서 외부 서비스 장애가 발생하면 어떻게 해결할 수 있을까?
우선 간단하게 타임아웃을 설정할 수 있다.
타임아웃
타임아웃은 시스템이 요청을 처리하거나 응답을 기다릴 때 일정 시간 내에 결과를 얻지 못할 경우, 해당 작업을 중단하고 다른 작업을 처리하도록 하는 메커니즘이다. 타임아웃에는 커넥션 타임아웃, 리드 타임아웃이 있다.
커넥션 타임아웃
클라이언트가 서버 측으로 연결을 맺길 원하지만 그러지 못한 경우 발생한다.
리드 타임아웃
리드(read) 타임아웃은 클라이언트와 서버가 커넥션은 맺어졌지만 I/O 작업이 길어지거나 데이터를 읽어가지 못하는 상황이 되어 타임아웃이 발생하는 경우이다.
그렇다면 다음과 같이
maeil-mail.kr
특정 서비스의 장애 때문에 전체 서비스가 영향을 받을 때는 벌크헤드 패턴을 적용해볼 수 있다.
벌크헤드 패턴
기능의 종류마다 자원 사용을 분리하는 방식으로, 자원이 격리되어 있기 때문에 서비스 일부에 장애가 발생해도 전체로 전파되지 않도록 보장해 준다. 위 예시의 경우 A, B, C 서비스를 분리하면 A서비스에 문제가 발생해도 B, C의 영향을 최소화할 수 있다.
그럼 이런 외부 서비스의 장애가 계속 발생하면 어떻게 될까? 계속 장애가 발생하는 서비스로 요청을 보내면 불필요하게 응답 시간이 길어지고 처리량도 감소하게 된다. 이런 경우에 서킷 브레이커를 적용할 수 있다.
서킷 브레이커
오류가 지속되는 경우 서킷 브레이커로 일정 시간 동안 기능의 실행을 차단할 수 있는데, 이로 인해 외부 서비스 장애에 의한 응답 시간 증가를 예방할 수 있다.