Cloud Tasks로 HTTP 요청 버퍼링

1. 소개

c6ac6ed05292f13e.png

Cloud Tasks는 대규모 태스크의 실행, 디스패치, 전송을 관리하는 완전 관리형 큐 서비스입니다.

Cloud Tasks를 사용하면 기본 애플리케이션 흐름 외부에서 독립적으로 수행할 수 있는 태스크라는 작업 (예: 데이터베이스 항목을 업데이트하는 태스크)을 분리하여 직접 만든 핸들러를 사용하여 비동기식으로 처리할 수 있습니다.

오프로드된 작업이 대기열에 추가되고, 대기열은 성공적으로 실행되거나 실패가 발생할 때까지 작업을 유지합니다. 구성에 따라, 대기열은 발송 흐름 제어의 역할을 할 수도 있습니다. 사용자가 큐를 만들고 구성한 다음 Cloud Tasks 서비스에서 관리합니다. 작업이 추가되면 대기열에서 작업을 전달하고 작업자가 안정적으로 처리할 수 있도록 합니다.

d59ffe8d34138c88.png

Cloud Tasks의 주요 기능은 다음과 같습니다.

  • HTTP 대상: 업계 표준 OAuth/OIDC 인증을 사용하는 안전한 방식으로 Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions, 온프레미스 시스템에서 실행 중인 HTTP 서비스를 대상으로 하는 태스크를 추가합니다.
  • 작업 중복 삭제: 여러 번 추가된 작업은 한 번만 디스패치됩니다.
  • 전송 보장: Tasks는 최소 1회 전송되도록 보장되며 대부분의 태스크는 정확히 한 번 전송됩니다.
  • 비율 및 재시도 제어: 태스크 디스패치 속도, 최대 시도 횟수, 각 시도 간 최소 대기 시간을 설정하여 실행을 제어합니다.
  • 미래 예약: 작업을 실행하는 시간을 관리합니다.

이 Codelab에서는 먼저 HTTP 대상 태스크를 위한 일반 Cloud Tasks 큐를 만들고 사용하는 방법을 알아봅니다. 그런 다음 큐 수준 HTTP URI 재정의와 새로운 BufferTask API를 사용하여 Cloud Tasks로 HTTP 요청을 보다 쉽게 버퍼링하는 방법을 알아봅니다.

학습할 내용

  • HTTP 대상 태스크를 만드는 방법
  • 새 큐 수준 HTTP URI 재정의로 HTTP target 태스크를 만드는 방법
  • 새로운 큐 수준 HTTP URI 재정의로 대기 중인 태스크를 변경하는 방법
  • 새로운 BufferTask API로 HTTP 요청을 더 쉽게 버퍼링하는 방법

2. 설정 및 요구사항

자습형 환경 설정

  1. Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
  • 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔은 고유한 문자열을 자동으로 생성합니다. 일반적으로는 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로 PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 다른 임의 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다.
  • 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
  1. 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스 또는 프로젝트를 삭제하면 됩니다. Google Cloud 신규 사용자는 300달러(USD) 상당의 무료 체험판 프로그램에 참여할 수 있습니다.

Cloud Shell 시작

Google Cloud를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.

Google Cloud Console의 오른쪽 상단 툴바에 있는 Cloud Shell 아이콘을 클릭합니다.

55efc1aaa7a4d3ad.png

환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다. 완료되면 다음과 같이 표시됩니다.

7ffe5cbb04455448.png

가상 머신에는 필요한 개발 도구가 모두 들어있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab의 모든 작업은 브라우저 내에서 수행할 수 있습니다. 아무것도 설치할 필요가 없습니다.

3. HTTP 대상 태스크를 위한 일반 큐 만들기

이 첫 번째 단계에서는 일반 Cloud Tasks 큐를 만들고 HTTP 태스크를 추가하여 Cloud Run 서비스를 타겟팅하는 방법을 알아봅니다.

d4f09a342c8eab.png

HTTP 대상 태스크란 무엇인가요?

HTTP 대상 태스크는 업계 표준 OAuth/OIDC 인증을 사용하여 Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions 또는 온프레미스 시스템에서 실행되는 모든 HTTP 서비스를 안전한 방식으로 타겟팅할 수 있습니다.

Cloud Run 서비스 배포

먼저 필수 API가 사용 설정되어 있는지 확인합니다.

gcloud services enable \
  cloudtasks.googleapis.com \
  run.googleapis.com

HTTP 작업의 대상으로 사용할 Cloud Run 서비스를 배포합니다.

SERVICE1=hello1
REGION=us-central1

gcloud run deploy $SERVICE1 \
  --allow-unauthenticated \
  --image=gcr.io/cloudrun/hello \
  --region=$REGION

Cloud Tasks 큐 만들기

일반 Cloud Tasks 큐를 만듭니다.

QUEUE1=http-queue
LOCATION=us-central1

gcloud tasks queues create $QUEUE1 --location=$LOCATION

HTTP 작업이 생성되는 즉시 관찰할 수 있도록 큐를 일시적으로 일시중지합니다.

gcloud tasks queues pause $QUEUE1 --location=$LOCATION

4. HTTP 태스크 만들기 및 테스트

이 단계에서는 앞에서 만든 큐를 대상으로 하는 HTTP 태스크를 만듭니다.

HTTP 태스크 만들기

gcloud를 사용하여 HTTP 태스크를 만들 수 있습니다.

gcloud tasks create-http-task \
    --queue=$QUEUE1 \
    --location=$LOCATION \
    --url=$SERVICE1_URL \
    --method=GET

선택사항: 클라이언트 라이브러리를 사용하여 HTTP 태스크를 만들 수도 있습니다. 예를 들어 HTTP 요청이 CloudTasksClient로 Cloud Tasks로 전송되기 전에 HTTP 요청이 TaskTaskRequest로 래핑된 C# 샘플의 Program.cs를 확인할 수 있습니다.

var taskRequest = new CreateTaskRequest
{
    Parent = new QueueName(projectId, location, queue).ToString(),
    Task = new Task
    {
        HttpRequest = new HttpRequest
        {
            HttpMethod = HttpMethod.Get,
            Url = url
        }
    }
};

var client = CloudTasksClient.Create();
var response = client.CreateTask(taskRequest);

다음과 같이 실행하여 작업을 만들어 대기열에 추가할 수 있습니다.

dotnet run $PROJECT_ID $LOCATION $QUEUE1 $SERVICE1_URL

HTTP 작업 테스트

이 시점에서 태스크는 생성되지만 큐가 일시중지되었으므로 아직 실행되지 않습니다. 큐를 나열하여 이를 확인할 수 있습니다.

gcloud tasks queues list --location=$LOCATION

큐가 PAUSED 상태로 표시됩니다.

QUEUE_NAME  STATE
http-queue  PAUSED

큐를 다시 시작합니다.

gcloud tasks queues resume $QUEUE --location=$LOCATION

Cloud Run 서비스의 로그를 확인합니다.

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE1" --limit 1

Cloud Run 서비스가 Cloud Tasks에서 HTTP GET 요청을 수신한 것을 확인할 수 있습니다.

httpRequest:
  latency: 0.227597158s
  protocol: HTTP/1.1
  remoteIp: 35.243.23.192
  requestMethod: GET
  requestSize: '415'
  requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/
  responseSize: '5510'
  serverIp: 216.239.32.53
  status: 200
  userAgent: Google-Cloud-Tasks

5. 라우팅 구성으로 큐 만들기

이 단계에서는 큐 수준 태스크 라우팅 구성 기능을 사용하여 HTTP URI 재정의를 추가하기 위해 라우팅 구성으로 Cloud Tasks 큐를 만드는 방법을 알아봅니다. 그런 다음 HTTP 태스크를 추가하여 첫 번째 Cloud Run 서비스를 타겟팅하고 라우팅 구성이 URI를 재정의하여 태스크를 두 번째 Cloud Run 서비스로 라우팅하는지 확인합니다.

5d1ec61a933f77.png

큐 수준 태스크 라우팅 구성이란 무엇인가요?

큐 수준 태스크 라우팅 구성은 모든 대기 중인 태스크와 새 태스크에 대한 전체 큐의 HTTP 태스크 라우팅을 변경합니다. 이렇게 하면 HTTP 대상을 작업 수준에서 설정할 필요가 없으므로 작업을 쉽게 생성할 수 있습니다. 또한 서비스 제공업체가 큐에 있는 모든 작업의 대상을 설정할 수 있으므로 (예: 원래의 백엔드가 다운된 경우 트래픽을 다른 백엔드로 라우팅) 서비스 제공업체가 더 많은 제어권을 가집니다.

큐 수준에서 다음 구성을 설정할 수 있습니다.

  • 헤더: 큐 레벨에서 지정된 경우 큐 수준 헤더로, 큐의 모든 태스크에 대한 헤더를 upsert합니다.
  • HTTP 메서드: 대기열 수준에서 지정된 HTTP 메서드는 대기열의 모든 작업에 대해 HTTP 메서드를 재정의합니다.
  • 대상 URI: 호스트, 경로, 쿼리, 포트, 스키마 (HTTP 또는 HTTPS)를 개별적으로 재정의할 수 있습니다.
  • 승인: 큐 수준에서 지정된 OIDC/OAuth 구성이 태스크 수준 OIDC/OAuth 구성을 재정의합니다.

두 번째 Cloud Run 서비스 배포

나중에 HTTP URI 재정의의 대상으로 사용할 두 번째 Cloud Run 서비스를 배포합니다.

SERVICE2=hello2
REGION=us-central1

gcloud run deploy $SERVICE2 \
  --allow-unauthenticated \
  --image=gcr.io/cloudrun/hello \
  --region=$REGION

나중을 위해 서비스 URL의 호스트를 저장합니다.

SERVICE2_URL=$(gcloud run services describe $SERVICE2 --region $REGION --format 'value(status.url)')
SERVICE2_HOST=$(echo $SERVICE2_URL | sed 's,http[s]*://,,g')

라우팅 구성으로 Cloud Tasks 큐 만들기

두 번째 Cloud Run 서비스에 대한 HTTP URI 재정의가 포함된 라우팅 구성으로 큐를 만듭니다.

QUEUE2=http-queue-uri-override

gcloud beta tasks queues create $QUEUE2 \
  --http-uri-override=host:$SERVICE2_HOST \
  --location=$LOCATION

URI 재정의는 두 번째 Cloud Run 서비스를 참조합니다. 큐에 추가된 모든 HTTP 태스크에는 원래 URI 호스트가 재정의됩니다. 큐 구성을 확인할 수 있습니다.

gcloud beta tasks queues describe $QUEUE2 --location=$LOCATION

httpTarget에 두 번째 서비스의 호스트를 가리키는 uriOverride가 있음을 확인할 수 있습니다.

httpTarget:
  uriOverride:
    host: hello2-idcwffc3yq-uc.a.run.app
    pathOverride: {}
    queryOverride: {}
...

HTTP 작업이 생성되는 즉시 관찰할 수 있도록 큐를 일시적으로 일시중지합니다.

gcloud tasks queues pause $QUEUE2 --location=$LOCATION

6. 라우팅 구성을 사용하여 큐에 대한 HTTP 태스크 만들기 및 테스트

이 단계에서는 첫 번째 서비스를 대상으로 하는 HTTP 작업을 만들고 URI가 두 번째 서비스를 가리키도록 큐에 의해 재정의되는지 확인합니다.

HTTP 태스크 만들기

첫 번째 서비스의 URL로 HTTP 태스크를 만듭니다.

gcloud tasks create-http-task \
    --queue=$QUEUE2 \
    --location=$LOCATION \
    --url=$SERVICE1_URL \
    --method=GET

HTTP 작업 테스트

큐를 다시 시작합니다.

gcloud tasks queues resume $QUEUE2 --location=$LOCATION

첫 번째가 아닌 두 번째 Cloud Run 서비스가 재정의로 인해 Cloud Tasks에서 HTTP GET 요청을 수신한 것을 확인할 수 있습니다.

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE2" --limit 1
---
httpRequest:
  latency: 0.228982142s
  protocol: HTTP/1.1
  remoteIp: 35.187.132.84
  requestMethod: GET
  requestSize: '426'
  requestUrl: https://hello2-idcwffc3yq-uc.a.run.app/
  responseSize: '5510'
  serverIp: 216.239.34.53
  status: 200
  userAgent: Google-Cloud-Tasks

7. 라우팅 구성으로 대기 중인 작업 변경

라우팅 구성을 사용하여 큐에서 대기 중인 모든 태스크의 HTTP URI를 변경할 수도 있습니다. 이 기능은 백엔드 서비스가 중단되어 다른 서비스로 빠르게 라우팅하려는 경우에 유용합니다. 이 단계에서는 어떻게 작동하는지 살펴보겠습니다.

큐를 다시 일시중지합니다.

gcloud tasks queues pause $QUEUE2 --location=$LOCATION

google.com를 태스크 URL로 사용하여 HTTP 태스크를 만듭니다.

gcloud tasks create-http-task \
    --queue=$QUEUE2 \
    --location=$LOCATION \
    --url=https://www.google.com \
    --method=GET

큐가 일시중지되어 태스크가 대기 상태입니다.

이제 첫 번째 서비스를 가리키도록 HTTP URI 재정의를 업데이트합니다. 이렇게 하면 대기 중인 작업의 호스트가 google.com에서 첫 번째 서비스의 호스트로 재정의됩니다.

SERVICE1_URL=$(gcloud run services describe $SERVICE1 --region $REGION --format 'value(status.url)')
SERVICE1_HOST=$(echo $SERVICE1_URL | sed 's,http[s]*://,,g')

gcloud beta tasks queues update $QUEUE2 \
  --http-uri-override=host:$SERVICE1_HOST \
  --location=$LOCATION

큐를 다시 시작합니다.

gcloud tasks queues resume $QUEUE2 --location=$LOCATION

재정의로 인해 첫 번째 Cloud Run 서비스가 Cloud Tasks에서 google.com 대신 HTTP GET 요청을 수신한 것을 확인할 수 있습니다.

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE1" --limit 1
---
httpRequest:
  latency: 0.228982142s
  protocol: HTTP/1.1
  remoteIp: 35.187.132.84
  requestMethod: GET
  requestSize: '426'
  requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/
  responseSize: '5510'
  serverIp: 216.239.34.53
  status: 200
  userAgent: Google-Cloud-Tasks

8. BufferTask API의 큐 만들기

일반적으로 gcloud 또는 Tasks 클라이언트 라이브러리에서 Tasks API를 사용하여 태스크를 만듭니다. 이로 인해 애플리케이션이 클라이언트 라이브러리를 사용하여 HTTP 요청을 Tasks로 래핑해야 하며 애플리케이션과 Tasks 클라이언트 라이브러리 간에 종속 항목도 생성됩니다.

이 단계에서는 큐 수준 HTTP URI 재정의와 새로운 BufferTask API를 활용하여 HTTP 요청을 전송하기만 하면 HTTP 대상 작업을 보다 쉽게 생성하는 방법을 알아봅니다. 이제 HTTP 요청을 보낼 수 있는 모든 애플리케이션이 HTTP 대상 작업을 만들 수 있습니다.

b1606516297fc4b6.png

BufferTask API란 무엇인가요?

CreateTask API는 Tasks를 만드는 기존의 방법이며 클라이언트가 모든 필수 필드가 설정된 API에 Task 객체를 보내야 합니다.

BufferTask API는 사용자가 작업 구성 (HTTP URL, 헤더, 승인)을 제공하지 않고도 HTTP 작업을 생성할 수 있는 새로운 기능으로, 이를 통해 개발자는 메시지나 요청 본문을 Buffer API로 간편하게 보낼 수 있습니다.

이제 클라이언트 측에서 코드를 변경하지 않고도 Cloud Tasks를 서비스 앞에 배포할 수 있으므로 서비스와 쉽게 통합할 수 있습니다. BufferTask API로 전송된 모든 임의 HTTP 요청은 Task 객체로 래핑되고 큐 수준에서 설정된 대상으로 전달됩니다.

BufferTask API를 사용하려면 대기열에 대상 URI 구성이 설정되어 있어야 합니다. 즉, BufferTask API를 사용하기 위한 기본 요건은 대기열 수준 라우팅 구성 기능입니다.

라우팅 구성으로 Cloud Tasks 큐 만들기

이전 단계에서 배포한 첫 번째 서비스를 가리키는 라우팅 구성으로 큐를 만듭니다.

SERVICE1=hello1
SERVICE1_URL=$(gcloud run services describe $SERVICE1 --region $REGION --format 'value(status.url)')
SERVICE1_HOST=$(echo $SERVICE1_URL | sed 's,http[s]*://,,g')
QUEUE3=http-queue-uri-override-buffer

gcloud beta tasks queues create $QUEUE3 \
  --http-uri-override=host:$SERVICE1_HOST \
  --location=$LOCATION

HTTP 작업이 생성되는 즉시 관찰할 수 있도록 큐를 일시적으로 일시중지합니다.

gcloud tasks queues pause $QUEUE3 --location=$LOCATION

9. BufferTask API로 HTTP 요청 버퍼링

이 단계에서는 BufferTask API를 사용해 간단한 HTTP GET 또는 POST 요청을 버퍼링합니다. Cloud Tasks는 이러한 HTTP 요청을 큐의 기본 라우팅 구성 설정을 사용하여 HTTP 태스크로 래핑합니다.

먼저 로그인하여 액세스 토큰을 가져오고 변수를 설정합니다.

gcloud auth application-default login
ACCESS_TOKEN=$(gcloud auth application-default print-access-token)
PROJECT_ID=$(gcloud config get-value project)
TASKS_QUEUES_API="https://cloudtasks.googleapis.com/v2beta3/projects/$PROJECT_ID/locations/$LOCATION/queues"

HTTP 태스크 만들기

BufferTask API를 사용해 HTTP 작업을 생성합니다. 태스크를 만들 필요가 없는 간단한 HTTP GET 요청입니다.

curl -X GET "$TASKS_QUEUES_API/$QUEUE3/tasks:buffer" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

HTTP POST와 본문을 사용하여 다른 HTTP 작업을 만듭니다.

curl -X POST "$TASKS_QUEUES_API/$QUEUE3/tasks:buffer" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d "{'message': 'Hello World'}"

선택사항: 클라이언트 라이브러리를 사용하여 HTTP 태스크를 만들 수도 있습니다. 예를 들어 HTTP GET 요청이 Task에 래핑하거나 Cloud Tasks용 클라이언트 라이브러리를 필요로 하지 않고 BufferTask API로 직접 전송되는 C# 샘플의 Program.cs를 확인할 수 있습니다.

var BufferTaskApiUrl = $"https://cloudtasks.googleapis.com/v2beta3/projects/{ProjectId}/locations/{Location}/queues/{Queue}/tasks:buffer";

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Add("Authorization", $"Bearer {AccessToken}");
    var response = await client.GetAsync(BufferTaskApiUrl);
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"Response: {content}");
}

다음과 같이 실행할 수 있습니다.

dotnet run $PROJECT_ID $LOCATION $QUEUE3 $ACCESS_TOKEN

BufferTask API는 HTTP 요청으로 Task를 생성하고 큐의 라우팅 구성 설정에 있는 URL을 URI에 추가합니다.

HTTP 작업 테스트

큐를 다시 시작합니다.

gcloud tasks queues resume $QUEUE3 --location=$LOCATION

Cloud Run 서비스가 Cloud Tasks에서 HTTP GET 및 POST 요청을 수신한 것을 확인할 수 있습니다.

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE1" --limit 4
---
httpRequest:
  latency: 0.002279292s
  protocol: HTTP/1.1
  remoteIp: 35.243.23.42
  requestMethod: POST
  requestSize: '777'
  requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/
  responseSize: '5450'
  serverIp: 216.239.32.53
  status: 200
  userAgent: Google-Cloud-Tasks
...
httpRequest:
  latency: 0.228982142s
  protocol: HTTP/1.1
  remoteIp: 35.187.132.84
  requestMethod: GET
  requestSize: '426'
  requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/
  responseSize: '5510'
  serverIp: 216.239.34.53
  status: 200
  userAgent: Google-Cloud-Tasks

10. 축하합니다

축하합니다. Codelab을 완료했습니다.

후속 조치로 Cloud Tasks를 Pub/Sub와 Cloud Run 사이의 버퍼로 사용하여 Cloud Tasks의 새로운 기능을 통해 서비스 간 버퍼 큐를 쉽게 만드는 방법에 대한 실제 예시를 확인할 수 있습니다.

삭제 (선택사항)

요금이 청구되지 않도록 하려면 리소스를 정리하는 것이 좋습니다.

프로젝트가 필요하지 않으면 프로젝트를 삭제하면 됩니다.

gcloud projects delete $PROJECT_ID

프로젝트가 필요한 경우 리소스를 개별적으로 삭제할 수 있습니다.

Cloud Run 서비스를 삭제합니다.

gcloud run services delete $SERVICE1 --region $REGION
gcloud run services delete $SERVICE2 --region $REGION

Cloud Tasks 큐를 삭제합니다.

gcloud tasks queues delete $QUEUE1 --location=$LOCATION
gcloud tasks queues delete $QUEUE2 --location=$LOCATION
gcloud tasks queues delete $QUEUE3 --location=$LOCATION

학습한 내용

  • HTTP 대상 태스크를 만드는 방법
  • 새 큐 수준 HTTP URI 재정의로 HTTP target 태스크를 만드는 방법
  • 새로운 큐 수준 HTTP URI 재정의로 대기 중인 태스크를 변경하는 방법
  • 새로운 BufferTask API로 HTTP 요청을 더 쉽게 버퍼링하는 방법