MSA - 서비스간 여러 통신 방법

salgu·2022년 10월 22일
0

Spring Cloud

목록 보기
9/9
post-thumbnail

환경


두개의 Spring Application, 1번 서버와 2번 서버가 통신을 하는 구조입니다.

동기 통신


1번 서버ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅣㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ→ 2번 서버
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅣ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ↓
ㅤㅤㅣ← ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅤ완료
ㅤㅤ↓ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤ 완료ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ

위의 구조로 통신을 하고있었고 처음으로 장애가 났을땐 Spring의 RestTemplate를 사용하여 동기로 요청했었습니다.
그러다 2번 서버의 장애가 생겨 1번 서버는 Blocking 상태가 되었고 timeout 설정을 하지않아 무한대기가 되었습니다.
이때 1번 서버의 서비스는 여러 기능들이 한 트랜잭션에 묶여있어 DB에 Lock 까지 걸려 더 큰 장애로 번지게 되었습니다.

비동기 통신


1번 서버ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅣㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ→ 2번 서버
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅣ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ↓
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ 완료
ㅤㅤ↓ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤ 완료ㅤ

장애 상황을 급한대로 해결하기 위해 비동기 통신, 스프링의 Web client로 변경을 하였고
2번 서버에 장애가 생겨도 비동기로 요청을 하였기 때문에 Blocking 상태에 빠지거나 하는 등 장애가 전파가 되지 않았습니다.
하지만 2번 서버의 로직이 실패하지 않고 성공을 보장해야 했기 때문에 적절하지 않는 방법이였습니다.

동기 통신, Curcuit Breaker


1번 서버ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅣㅤ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅣㅡㅡ(Curcuit Breaker)ㅡㅡ→ 2번 서버
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅣ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ↓
ㅤㅤㅣ← ㅡㅡ(Curcuit Breaker)ㅡㅤ완료
ㅤㅤ↓ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤ 완료

서킷브레이커를 통하여 2번 서버의 로직의 결과를 알 수 있었고
장애시 Time out 설정과 성공률 체크 등 옵션을 사용하여 서킷브레이커를 열고
요청이 실패 시 fallback 기능을 활용하여 Return 값을 커스텀해 유연하게 대처를 할 수 있게 되었습니다.
하지만 2번 서버의 성공을 보장하고 싶었고
서버1과 서버2가 강하게 결합되어 있어 의존성을 분리하고 싶었습니다.

Messaging 전송 방식


1번 서버ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ ㅤ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅣ ㅡㅡ→ Kafka pub-sub ㅡㅡ→ 2번서버
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ ㅤㅤㅤㅤ ㅣ
ㅤㅤㅣㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ ㅤㅤㅤ ㅤㅤ↓
ㅤㅤ↓ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ ㅤㅤ완료
ㅤ 완료

kafka의 메세징 전송 방식을 사용하였고
1번 서버에서는 kafka에게만 전송하고
2번 서버는 kafka에서 데이터만 받아
1번 서버와 2번 서버는 서로의 정체에 대해 모릅니다.
이렇게 의존성이 완전히 분리되었고
kafka는 producer로 전송받았던 데이터를 토픽의 파티션에 저장하고 있고 각 comsumer 마다 offset이 있기 때문에 consumer가 데이터를 받지 못했던 시점을 알 수 있어 성공을 보장할 수 있었습니다.

profile
https://github.com/leeeesanggyu, leeeesanggyu@gmail.com

0개의 댓글