코딩스토리

Cloud Run에 Pub/Sub 사용하기 듀토리얼 본문

Google Cloud Platform

Cloud Run에 Pub/Sub 사용하기 듀토리얼

kimtaehyun98 2022. 7. 11. 19:38

# 해당 포스팅은 GCP 공식 문서 내용을 바탕으로 작성된 글입니다.

https://cloud.google.com/run/docs/tutorials/pubsub?hl=ko#run-clone-sample-repository-java 

 

Cloud Run에 Pub/Sub 사용 튜토리얼  |  Cloud Run 문서  |  Google Cloud

의견 보내기 Cloud Run에 Pub/Sub 사용 튜토리얼 이 튜토리얼에서는 Cloud Run 서비스를 작성, 배포하고 Pub/Sub 푸시 구독으로부터 호출하는 방법을 보여줍니다. 목표 Cloud Run에 서비스 작성, 빌드, 배포 P

cloud.google.com

 

개요

 

앞서 Cloud Pub/Sub이 뭔지, 어떻게 사용하는 건 지 알아보았다.

그리고 Cloud Pub/Sub이 많은 서비스(특히 GCP)와 연동하여 사용할 수 있음을 알 수 있었다.

그럼 이번엔 실제로 Google Cloud Run이란 서버리스 서비스와 연동시켜보자.

 

 

Google Cloud Run이란?

 

잠시 Cloud Run에 대해서 빠르게 얘기하고 넘어가자면,

 

공식 문서에서는 Cloud Run을 " Google의 확장 가능한 인프라에서 직접 컨테이너를 실행할 수 있게 해 주는 관리형 컴퓨팅 플랫폼입니다."라고 소개하고 있다.

 

https://cloud.google.com/run/docs/overview/what-is-cloud-run?hl=ko 

 

Cloud Run이란 무엇인가요?  |  Cloud Run 문서  |  Google Cloud

의견 보내기 Cloud Run이란 무엇인가요? Cloud Run은 Google의 확장 가능한 인프라에서 직접 컨테이너를 실행할 수 있게 해 주는 관리형 컴퓨팅 플랫폼입니다. 컨테이너 이미지를 빌드할 경우 모든 프

cloud.google.com

 

Cloud Run은 서버리스 서비스이다.

 

기존의 Lambda 같은 서버리스 Function들은 언어의 제약을 받았었다.

하지만 Cloud Run은 컨테이너 기반으로 작동한다.

 

아래의 그림을 보면 Client의 요청을 받았을 때 "컨테이너 인스턴스"가 실행되는 것이다.

이게 무슨 말이냐 하면, 컨테이너가 실행되면 된다는 것이다.

즉, Lambda처럼 함수를 실행시키는게 아니고 Docker 같은 컨테이너를 실행시키면 된다는 것이다.

 

컨테이너는 코드들을 한 단계 감싸고 있기 때문에 (이 표현이 적절한 진 모르겠지만 이해는 가장 쉬운 것 같아서)

언어와 코드 형식에 제약을 받지 않게 되는 것이다.

 

갑자기 왜 이런 급발진을 하는가에 대한 대답은 튜토리얼 중간에 "코드 제공은 Cloud Build로 컨테이너 이미지를 빌드하고, Container Registry에 컨테이너 이미지를 업로드하고, 컨테이너 이미지를 Cloud Run에 배포하는 세 단계로 구성됩니다." 라고 쓰여있기 때문이었다.

 

여기서 이미지란 내가 만든 서비스, 즉 현재는 Spring 서버라고 생각하면 된다.

 

프로젝트 생성

 

 

 

결제상태확인 -> 가입할 때 결제 설정했으면 문제없는 듯? (그리고 무료 크레딧도 있어서)

걱정되면 링크 따라해보기

 

API 사용 설정

 

약 30초~1분 정도 기다리면 활성화된다.

 

다음으로 Google Cloud CLI를 설치하라고 함

앞선 포스팅들을 따라왔다면 (Pub/Sub 포스팅) 아마 gcloud를 쓸 수 있겠지만 그렇지 않다면 이것도 링크 따라가서 하기

(링크 들어가서 보니 설명이 너무 잘되어 있어서 이걸 보고 했다면 이전에 내가 설치할 때 많은 시간을 아낄 수 있지 않았을까.. 역시 구글)

 

그다음 터미널 창에서 component update 실행

 

gcloud components update

 

 

gcloud 기본값 설정

먼저 프로젝트 ID를 알고 있어야 한다. (계속 기억해놓기. 뒤에도 쓰임)

 

 

프로젝트 ID를 설정했으면, 리전을 설정해야 한다.

리전은 실제 클라우드 서버가 있는 지역이라고 이해하면 된다.

 

 

서울도 있는 것을 확인할 수 있다. 

등급은 읽어보면 알겠지만 지금 당장 튜토리얼에는 큰 의미가 없다.

 

# Project ID 설정
gcloud config set project 자신의_PROJECT_ID

# Project Region 설정 (서울로 설정)
gcloud config set run/region asia-northeast3

 

 

Pub/Sub 주제 만들기

 

앞 선 포스팅에서 Pub/Sub을 다뤘었지만... 혹시나 과금 이슈가 생길까 봐 삭제했다.

 

그래서 다시 만들어야 됨 ㅎ..

 

이번엔 그대로 입력하자. (분명 myRunTopic으로 주제 이름을 정하지 않으면 후회할 것 같은 느낌이 강하게 든다..! 🙃

gcloud pubsub topics create myRunTopic

 

샘플 코드 

 

샘플 코드를 다양한 언어로 제공해주고 있다.

 

나는 Java를 쓰고 있기 때문에 해당 샘플 코드를 받아왔다. (웬만하면 Git으로 받는 게 편할 듯?)

 

자신이 원하는 폴더로 이동한 뒤 clone 받아오면 된다.

 

clone이 완료되면 해당 폴더로 이동한다. (아니 구글에서는 폴더 이동까지 복붙 하게 해 준다고?!?!?!)

 

git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

cd java-docs-samples/run/pubsub/

 

 

코드 분석

 

코드 분석이라고 하기도 민망하지만..

 

일단 SpringBoot 서버임을 확인할 수 있다. 

 

그리고 Controller와 DTO가 하나 있는데 구조는 어렵지 않다. (구글도 MVC 패턴을 사용한다고?!) 

 

그럼 Controller만 살펴보자.

// PubsubController consumes a Pub/Sub message.
@RestController
public class PubSubController {
  @RequestMapping(value = "/", method = RequestMethod.POST)
  public ResponseEntity receiveMessage(@RequestBody Body body) {
    // Get PubSub message from request body.
    Body.Message message = body.getMessage();
    if (message == null) {
      String msg = "Bad Request: invalid Pub/Sub message format";
      System.out.println(msg);
      return new ResponseEntity(msg, HttpStatus.BAD_REQUEST);
    }

    String data = message.getData();
    String target =
        !StringUtils.isEmpty(data) ? new String(Base64.getDecoder().decode(data)) : "World";
    String msg = "Hello " + target + "!";

    System.out.println(msg);
    return new ResponseEntity(msg, HttpStatus.OK);
  }
}

 

듀토리얼에서는 "Pub/Sub 메시지를 처리하고 인사말을 로깅하는 핸들러입니다."라고 소개하고 있다.

 

코드를 분석해보려고 한 번 읽어봤는데 어.. 설명할 부분이 딱히 없네요..🥴

 

그래서 결론적으로 해당 코드는 데이터가 들어오면 "Hello" + "입력한 데이터" + "!" 이런 식으로 반환하는 컨트롤러이다.

 

 

코드 제공

 

 

앞 서 Cloud Run이 뭔지 설명했다.

큰 틀은 저렇다고 보면 된다. (위에 그림을 보면 볼수록 진짜 완벽히 설명하고 있는 그림이 아닌가 싶어 재탕했습니다..!)

 

그럼 다시 튜토리얼을 따라가 보자.

gcloud auth configure-docker

 

위의 명령어를 치면 아래와 같은 경고들이 나올 것이다.

WARNING: `docker` not in system PATH.
`docker` and `docker-credential-gcloud` need to be in the same PATH in order to work correctly together.
gcloud's Docker credential helper can be configured but it will not work until this is corrected.
Adding credentials for all GCR repositories.
WARNING: A long list of credential helpers may cause delays running 'docker build'. We recommend passing the registry name to configure only the registry you are using.
After update, the following will be written to your Docker config file located 
at [/Users/taehyun/.docker/config.json]:
 {
  "credHelpers": {
    "gcr.io": "gcloud",
    "us.gcr.io": "gcloud",
    "eu.gcr.io": "gcloud",
    "asia.gcr.io": "gcloud",
    "staging-k8s.gcr.io": "gcloud",
    "marketplace.gcr.io": "gcloud"
  }
}

 

당황하지 않고~ 열심히 구글링을 하다 보니 아래와 같은 과정으로 해결할 수 있다고 한다.

gcloud components install docker-credential-gcr

 

docker-credential-gcr configure-docker

위 명령어 쳤을 때도 에러가 난다면 Docker가 설치되어 있지 않아서 그런 것이다.

 

Docker를 얼른 설치하고 다시 실행해보면 정상적으로 실행된다.

 

그러고 나서 이제 아래 명령어를 치면!

mvn compile jib:build -Dimage=gcr.io/자신의_PROJECT_ID/pubsub

 

또 mvn 없다고 zsh 에러 뜬다.. 

아.. 개발자의 삶은 왜 이렇게 고단한가.. 

내가 지금 그나마 mac으로 하고 있어서 설치가 쉬운 거지 만약 window로 했으면..

 

어쨌든 mac에서 maven 다운받으려면 brew install maven 하면 된다. (물론 homebrew가 깔려있다는 가정하에..)

그러고 터미널 껐다 켜서 mvn -v 치면 아래와 같이 나오면 정상적으로 다운된 것이다.

 

 

이제 다시 mvn 명령어 입력해주면 

 

빌드에 실패한다.

 

그래. 누가 이기나 보자.

 

Error 읽어 보니 Pom 파일이 directory에 없다는데 문득 든 생각은 내가 dir를 프로젝트 다운로드한 곳이 아닌 다른 곳으로 왔었다.

 

다시 아래 명령어 치고

cd java-docs-samples/run/pubsub/

 

rebuild 해보면 이게 맞나 싶을 정도로 엄청 많은 것들을 다운로드한다.

(mac 산지 얼마 안 됐는데 불안해ㅠㅠㅠ 😭😭😭)

 

한 체감상 5분? 냅두면 아래처럼 build 성공을 확인할 수 있다.

이제 build에 성공했으니 배포를 해보자.

gcloud run deploy pubsub-tutorial --image gcr.io/자신의_PROJECT_ID/pubsub --no-allow-unauthenticated

 

참고로 공식 Tutorial 페이지에 있는 명령어를 복붙 하면 에러가 난다.

ERROR: (gcloud.run.deploy) unrecognized arguments:  --no-allow-unauthenticated

그냥 저 부분에 공백이 하나 더 들어가서 인식을 못하는 것이므로 붙여서 다시 입력해주면 된다. (바로 위의 코드가 수정한 코드!)  

 

배포 성공!

여기서 하단의 Service URL : ~라고 적혀있는 부분 꼭  기억해놓아야 함!!! (밑에서 쓰임)

Pub/Sub와 통합

현재까지의 과정은 Cloud Run을 배포한 것이다.

 

이제 해야 될 일은 이 Cloud Run에게 메세지를 줄, 메세지 큐 역할을 할 Cloud Pub/Sub과 연동해야 한다. 

(여기서 Cloud Run이 Subscriber 역할을 하게 되는 것이다. 이 부분이 이해가 안 된다면 아래의 포스팅에서 확인!)

https://kimtaehyun98.tistory.com/146

 

What is Cloud Pub/Sub? - ep.2

# 해당 포스팅은 Google Cloud Tech Youtube의 Cloud Pub/Sub 관련 영상을 기반으로 작성하였습니다. What is Cloud Pub/Sub? -ep2 앞선 포스팅의 내용은 왜 Cloud Pub/Sub 모델이 등장했는지에 대한 설명이었다...

kimtaehyun98.tistory.com

 

이제 서비스 계정을 만들어주어야 한다.

 

명령어 그대로 입력하면 알아서 만들어준다.

(튜토리얼 보면 보라색으로 서비스 계정 명을 변경할 수 있게 해 주지만 굳이..? 어차피 삭제할 거라 그냥 하는 게 편한 것 같다.) 

gcloud iam service-accounts create cloud-run-pubsub-invoker \
     --display-name "Cloud Run Pub/Sub Invoker"

다음은 권한 추가하는 건데 여기서 PROJECT_ID만 바꿔주면 된다. (이래서 위에서 그대로 쓰는 게 편함 ㅎㅎ)

gcloud run services add-iam-policy-binding pubsub-tutorial \
   --member=serviceAccount:cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com \
   --role=roles/run.invoker

다음으로 역시 권한 관련된 작업이다.

gcloud projects add-iam-policy-binding PROJECT_ID \
     --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
     --role=roles/iam.serviceAccountTokenCreator

이때 project number는 맨 위에 사진에서 Google Cloud 처음 들어가면 환영합니다 화면에 보면 나와있다.

 

 

이제 해당 서비스 계정으로 Subscription을 만든다. (이 부분도 이해가 안 간다면 이전 포스팅을!)

gcloud pubsub subscriptions create myRunSubscription --topic myRunTopic \
   --ack-deadline=600 \
   --push-endpoint=SERVICE-URL/ \
   --push-auth-service-account=cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com

여기서 앞서 myRunTopic으로 했기 때문에 Service URL과 Project ID만 바꾸면 된다.

 

이렇게 하면 두둥!

성공적으로 구독했음을 확인할 수 있다.

(이제 거의 다 왔어요~!! 😭)

 

사용해 보기

 

현재 아키텍처는 다음과 같다.

더 자세히 보자면 Pub/Sub 내부에서 myRunTopic이란 주제를 Cloud Run이 Subscription 하고 있는 형태일 것이다.

(더 자세히 그릴까 했는데 지금 이 글을 작성하고 있는 곳이 너무 에어컨이 빵빵해서 손이 얼어가는 중이라 일단 빨리 탈출 ❄️

 

그럼 이제 구독하고 있는 Cloud Run에게 Pub/Sub에서 메시지를 날려보자.

 

gcloud pubsub topics publish myRunTopic --message "본인 이름"

 

아까 Controller 설명할 때 분석했듯이 "Hello [본인 이름]!"을 Cloud Run이 출력하면 정상이다.

 

일단 CLI론 정상적으로 메시지를 보냈다.

즉 Pub/Sub은 정상적으로 구독자에게 메시지를 전송(게시)했다.

 

이제 정상적으로 System.out.println() 찍었는지 보려면 Cloud Run Consol로 간다. (링크는 공식 문서에 있습니다!)

 

그리고 로그 탭으로 들어가면

예상했던 대로 정상적으로 출력하고 있음을 확인할 수 있다!!! 👍👍👍

 

이렇게 Cloud Run과 Pub/Sub을 사용한 튜토리얼을 완료했다.

 

이제까지 Pub/Sub의 역할에 대해 이해하고, 실제 다른 서비스를 추가시켜 보니 도움이 많이 됐다.

 

사실 나는 이 Pub/Sub과 Cloud Run을 사용한 크롤러를 만들어야 하기 때문에 해 봤지만 저비용 설계를 꿈꾸고 있다면 한 번 시도해보는 것도 굉장히 좋은 경험일 것 같다.

 

꼭 서비스 삭제하는 거 까먹지 마시길..! (안 그럼 과금 이슈 생길 수 있어요~!!)

Comments