오늘은 통신 패턴에 대해서 알아보자.
통신 패턴은 크게 요청/응답, 발행/구독, 단방향, 요청/확인응답, 스트림으로 나누어 볼 수 있다.
클라이언트가 서버에 요청을 보내고 서버가 응답을 반환하는 방식이다.
클라이언트와 서버는 요청 후 응답을 받을 때까지 대기하며 동기적으로 처리된다. 호출과 응답은 1:1의 관계를 갖는다.
DB 쿼리 요청이나 HTTP REST API 호출 등이 이에 해당한다.
요청/응답은 동기와 비동기로도 나눌 수 있다.
클라이언트는 비동기로 요청을 보내고 서버는 요청을 동기적으로 처리 후에 응답한다.
따라서 클라이언트는 다른 작업을 하다가 응답 수신 시 처리할 수 있고 서버는 요청 처리 중 다른 작업을 하지 못한다.
Python asyncio + requests 호출이 이에 해당한다.
클라이언트는 요청 후 응답을 기다리고 서버는 요청을 비동기로 처리한다.
따라서 클라이언트는 응답이 올 때까지 대기하고 서버는 이벤트 기반으로 동시에 여러 요청 처리가 가능하다.
Nginx reverse proxy가 이에 해당한다.
클라이언트와 서버 모두 비동기 방식으로 요청을 보내고 처리한다. 따라서 높은 처리량과 응답성을 가지며 서버-클라이언트 모두 논블로킹으로 효율적인 자원 사용이 가능하다.
Kafka Streams API가 이에 해당한다.
클라이언트가 요청을 보내면 서버가 요청을 받았음(Ack)을 응답한다. 데이터 처리 결과가 아닌 수신 확인이 목적이다.
처리 시간이 오래 걸리는 요청에 대해 즉시 최종 결과를 주기 어렵고, 최소한 "요청은 정상적으로 접수되었다"라는 확인이 필요할 때 사용한다.
쇼핑몰에서 주문 버튼 클릭 후 화면에 주문번호가 표시, ATM 송금 버튼 클릭 수 "송금 요청이 접수되었습니다"가 표시 등이 이에 해당된다.
발행자(Publisher)가 메시지를 특정 주제(Topic)에 발행하고, 구독자(Subscriber)는 원하는 주제를 구독해 메시지를 수신한다.
호출과 응답은 비동기적으로 처리되는 느슨한 결합 구조이며, N:M 관계를 갖는다.
Kafka, RabbitMQ 등이 이에 해당한다.
메시지 큐의 기본 패턴은 발행/구독 패턴이지만 요청/확인응답도 포함된다.
메시지를 Broker(Kafka, RabbitMQ)에 발행했을때 Producer가 메시지를 보내면 Broker가 메시지를 받았다(Ack)는 응답을 보낸다.
클라이언트가 서버에 요청을 보내지만 응답을 기다리지는 않는 방식이다.
응답을 기다리지 않기 때문에 빠르지만 신뢰성이 낮고, 실패 여부를 알 수없다.
로깅 시스템, Metrics 전송, kafka Producer acks=0 설정 등이 이에 해당한다.
한쪽 또는 양쪽이 지속적으로 데이터를 흘려보내는 통신을 의미한다.
실시간 처리, 대용량 데이터 처리에 적합하며 연결을 유지하면서 여러 메시지를 주고받을 수 있다.