본문 바로가기

컴퓨터/클라우드

[GCP Associate Cloud Engineer] Pub/Sub

애플리케이션이 다른 서비스와 데이터를 주고받을 때 동기식 통신이 필요한 경우가 많다. 예를 들어, 웹 서버에 있는 애플리케이션이 로그를 저장하기 위해 로그 서비스에 동기적으로 요청을 보낸다고 가정해보자.

웹 서버는 로그를 남기기 위해 로그 서비스에 요청을 보낸 후 응답을 기다린다.

로그 서비스는 받은 로그 데이터를 데이터베이스에 저장한다.

따라서, 로그 서비스가 정상적으로 동작하면, 웹 서버는 문제없이 로그를 기록할 수 있다.

그러나 이 방식에는 몇 가지 문제점이 존재한다.

 

로그 서비스가 다운될 경우

만약 로그 서비스가 다운되면, 웹 서버도 로그를 남길 수 없게 된다.

더 나쁜 경우, 로그를 남기려다 웹 서버 전체가 멈출 수도 있다.

 

트래픽이 급격히 증가할 경우

갑자기 많은 로그가 발생하면, 로그 서비스는 과부하 가 걸릴 수 있다.

처리량을 초과하면 로그 서비스가 다운될 가능성이 커지고, 결국 웹 서버에도 영향을 줄 수 있다.

이런 문제를 해결하기 위해 애플리케이션과 로그 서비스를 분리하는 방법이 필요하다.

비동기 방식(PubSub)으로 디커플링

애플리케이션과 로그 서비스를 분리하기 위해 PubSub(Publish-Subscribe) 모델을 사용할 수 있다.

Pub/Sub은 신뢰성이 높고 확장 가능하며, 완전 관리형 비동기 메시징 서비스이다.
이는 특히 Google Cloud의 고가용성 및 고확장성 솔루션의 핵심 이 된다.

일일 최대 10억 개 이상의 메시지 처리 가능하고, 서버 확장을 신경 쓰지 않아도 자동 확장 지원한다.

웹 애플리케이션이 로그를 남길 때, 로그 서비스에 직접 요청하지 않고 토픽에 메시지를 보낸다.

로그 서비스는 필요할 때 토픽에서 메시지를 가져와 처리한다.

이 방식을 사용하면 웹 서버와 로그 서비스가 서로 독립적으로 동작할 수 있다.

 

 - 토픽(Topic): 메시지가 전달되는 중간 저장소

 - 퍼블리셔(Publisher): 메시지를 발행하는 역할 

 - 서브스크라이버(Subscriber): 메시지를 구독하는 역할 

 

PubSub 방식의 장점

 

디커플링

웹 서버는 로그 서비스가 존재하는지 여부를 신경 쓰지 않는다.

로그 서비스가 다운되더라도, 메시지가 토픽에 저장되므로 나중에 처리 가능하다.

 

가용성 향상

로그 서비스가 일시적으로 다운되더라도, 로그 메시지는 토픽에 남아있다.

로그 서비스가 복구되면 토픽에서 메시지를 가져와 정상적으로 처리할 수 있다.

 

확장성

로그 메시지가 많아지면, 로그 서비스 인스턴스를 여러 개 배포하여 부하를 분산할 수 있다.

이를 통해 높은 트래픽에도 원활하게 대응 가능하다.

 

내구성

로그 서비스가 다운되더라도 메시지가 유실되지 않는다.

로그 서비스가 다시 실행되면 남아 있는 메시지를 계속 처리할 수 있다.

 

Pub/Sub의 주요 활용 사례

 

이벤트 스트리밍

다수의 이벤트가 발생할 때, 이를 Pub/Sub 토픽에 저장하고 필요한 소비자가 메시지를 가져가서 처리하도록 할 수 있다.

 

스트리밍 분석 파이프라인

실시간 분석이 필요한 대규모 데이터 스트림 처리에 적합하다.

데이터를 Pub/Sub에 저장한 후, 분석 및 최종 데이터 저장소로 이동 가능하다.

 

Pub/Sub 메시지 전송 방식

Pub/Sub에서 메시지를 주고받는 과정은 토픽 생성 → 구독 생성 → 메시지 전송 → 메시지 수신 및 확인 의 순서로 진행된다.

Pub/Sub에서는 퍼블리셔가 메시지를 토픽으로 전송하고, 서브스크라이버가 메시지를 가져가서 처리한다.

 

토픽 생성

퍼블리셔는 먼저 Pub/Sub에서 토픽을 생성한다.

이 토픽은 메시지를 전달하는 중심 채널 역할을 한다.

퍼블리셔는 이 토픽으로 메시지를 보낸다.

 

구독 생성

토픽에 구독을 생성하면, 서브스크라이버가 토픽을 구독할 수 있다.

구독은 토픽에서 메시지를 받을 수 있는 개별적인 메시지 풀을 의미한다.

각 구독은 독립적으로 존재하며, 특정 서브스크라이버와 연결된다.

 

여러 개의 구독이 존재할 경우 예를들어 토픽에 10개의 메시지가 게시되면, 모든 구독에 동일한 10개 메시지가 전달된다.

즉, 각 구독이 모든 메시지를 개별적으로 받는다.

하나의 구독에 여러 클라이언트가 연결된 경우는 메시지는 자동으로 분산 처리 된다.

예를 들어, 구독1에 클라이언트 A, B, C가 연결되어 있다면, 메시지가 A, B, C에게 균등하게 배분된다.

 

메시지 전송

퍼블리셔가 생성된 토픽으로 메시지를 보낸다.

Pub/Sub은 이 메시지를 각 구독에 개별적으로 전달한다.

 

메시지 수신

서브스크라이버는 메시지를 받는 방식에 따라 풀 또는 푸시 방식 중 하나를 선택할 수 있다.

 

 - 풀 방식

구독자가 준비되었을 때, 직접 메시지를 요청하여 가져가는 방식이다.

서브스크라이버가 HTTPS 요청을 보내어 Pub/Sub에게 메시지가 있는지 묻는다.

Pub/Sub은 메시지가 있으면 제공하고, 없으면 "없음"으로 응답한다.

 

 - 푸시 방식

메시지가 토픽에 게시되자마자 즉시 서브스크라이버에게 자동으로 전달된다.

서브스크라이버가 웹훅 엔드포인트를 등록한다.

메시지가 생성되면 Pub/Sub이 해당 엔드포인트로 HTTP POST 요청을 자동 전송한다.

 

메시지 확인

서브스크라이버가 메시지를 정상적으로 처리하면 확인 신호를 Pub/Sub에 보낸다.

메시지는 해당 구독에서 제거되며, 처리 완료됨을 보장한다.

각 구독은 개별적인 메시지 큐를 가지고 있고, 하나의 메시지는 모든 구독에 개별적으로 존재한다.

각 구독에서 해당 메시지를 확인해야만 해당 구독에서 삭제되기 때문에 구독이 메시지를 확인해도, 다른 구독의 메시지는 그대로 유지된다.

 

 

Google cloud에서 Pub/Sub

 

토픽 생성을 통해 토픽 이름을 입력하고 생성하면 아래와 같이 생성을 할 수 있다.

토픽 생성 완료

 

추가 구독 생성하기 위해서 구독 만들기를 선택하여 구독 방식, 메시지 보존 기간, 구독 만료 기간등을 설정하여 추가적인 구독을 생성할 수 있다. 

구독 생성

구독을 생성한 뒤 메시지 보내기를 통해 각각의 구독에 메시지를 전송할 수 있다.

메시지 게시

메시지를 조회하면 각각의 구독에 동일한 메시지가 표시된다.

즉, 각 구독은 게시된 모든 메시지를 개별적으로 수신하고, 서로 다른 구독이므로 개별적으로 메시지를 처리해야 한다.

 

메시지 수신

이때 확인 메시지 사용 설정을 선택하면 해당 메시지를 수신했는지 확인을 따로 할 수 있는데 이때 각 구독은 개별적인 메시지 큐를 가지기 때문에 한 쪽에서 확인을 해도 다른쪽에는 그대로 남아 있는다.

메시지 확인

 

gcloud CLI에서 Pub/Sub

 

토픽 생성

Pub/Sub에서 사용할 토픽을 생성한다.

gcloud pubsub topics create topic-from-gcloud

 

구독 생성

토픽을 생성했으므로, 해당 토픽을 구독할 서브스크라이버를 위한 구독을 생성한다.

gcloud pubsub subscriptions create subscription-gcloud-1 --topic=topic-from-gcloud

subscription-gcloud-1: 생성할 구독의 이름

--topic=topic-from-gcloud: 구독할 토픽 지정

 

메시지 게시

이제 토픽에 메시지를 게시해본다.

gcloud pubsub topics publish topic-from-gcloud --message="My First Message"

--message="My First Message": 게시할 메시지 내용

위 명령어를 여러 번 실행하여 메시지를 추가로 게시할 수 있다.

 

구독에서 메시지 가져오기

메시지가 정상적으로 게시되었는지 구독에서 메시지를 가져와 확인한다.

gcloud pubsub subscriptions pull subscription-gcloud-1

메시지 ID와 함께 ACK_ID도 표시된다.

만약 여러개의 구독이 있다면 구독은 개별적으로 메시지를 관리하기 때문에, 각각의 구독에서 메시지를 가져올 수 있다.

 

메시지 확인

구독에서 받은 메시지를 처리했음을 확인해야 메시지가 삭제된다.

gcloud pubsub subscriptions pull subscription-gcloud-1 --auto-ack

# 수동으로 Ack 처리하기
gcloud pubsub subscriptions pull subscription-gcloud-1

--auto-ack 옵션을 사용하면 메시지를 자동으로 확인 처리하여 구독에서 삭제할 수 있다.

 

수동으로 Ack 처리할 경우 아래와 같은 결과가 출력이 되는데 이 경우 해당 메시지의 ID를 통해서 확인할 수 있다.

수동 Ack 처리 결과

gcloud pubsub subscriptions acknowledge subscription-gcloud-1 --ack-ids=2079597651818060

--ack-ids=2079597651818060: 메시지의 Ack ID를 지정하여 해당 메시지만 Ack 처리

Ack 처리되지 않은 메시지는 다시 구독으로 전달된다.