프록시리스 gRPC 서비스로 고급 트래픽 관리 구성

이 문서에서는 다음 라우팅 기능으로 Traffic Director를 구성하는 방법을 설명합니다.

  • 경로 일치
  • 트래픽 분할
  • 회로 차단
  • 결함 주입
  • 최대 스트림 지속 시간

이 문서에서는 Compute Engine에서 프록시리스 gRPC로 고급 트래픽 관리 설정에 대해 집중적으로 설명하지만, Google Kubernetes Engine(GKE)에서 프록시리스 gRPC를 사용할 때에도 고급 트래픽 관리가 지원됩니다.

시작하기 전에

고급 트래픽 관리를 구성하기 전에 프록시리스 gRPC 서비스로 Traffic Director 설정 준비의 요구사항을 검토합니다. 요구사항이 모두 충족되지 않은 한 고급 트래픽 관리를 구성할 수 없습니다.

이러한 기능의 개념은 고급 트래픽 관리를 참조하세요.

gRPC 월렛 예시 정보

이러한 기능을 설명하기 위해 gRPC 월렛 예시를 배포합니다. 다음 다이어그램과 같이 wallet-service, stats-service, account-service용 백엔드 서비스를 만듭니다.

gRPC 월렛 트래픽 라우팅 구성 예시
gRPC 월렛 트래픽 라우팅 구성 예시(확대하려면 클릭)

이 예시에서는 구성한 규칙에 따라 각 서비스의 여러 버전을 배포하여 요청 라우팅을 보여줍니다. 여러 서비스 버전의 빌드와 배포를 시뮬레이션하도록 서버 플래그를 사용하여 한 번만 빌드하는 바이너리의 동작을 변경합니다.

  • --port 플래그는 백엔드 VM의 서비스가 리슨하는 포트를 지정합니다.
  • --hostname_suffix 플래그는 요청에 응답하는 VM의 호스트 이름에 추가되는 값을 지정합니다. 결과 값은 응답에 hostname 메타데이터로 추가됩니다. 이렇게 하면 클라이언트 요청에 응답한 백엔드 서비스의 인스턴스를 식별할 수 있습니다.
  • --premium_only 플래그를 true 값으로 지정하면 서비스가 stats 서비스의 프리미엄 버전으로 지정됩니다.
  • --v1_behavior 플래그를 true 값으로 지정하면 월렛 바이너리가 v1 버전으로 동작합니다.

다음 표에는 월렛 예시의 각 백엔드 서비스(서비스), 인스턴스 그룹, 인스턴스에 대한 이러한 플래그 값이 나와 있습니다.

백엔드 서비스 인스턴스 그룹 인스턴스 서버 플래그
account account 2 --port=50053
--hostname_suffix="account"
stats stats 2 --port=50052
--hostname_suffix="stats"
--account_server="xds:///account.grpcwallet.io"
stats-premium stats-premium 2 --port=50052
--hostname_suffix="stats_premium"
--account_server="xds:///account.grpcwallet.io"
--premium_only=true
wallet-v1 wallet-v1 2 --port=50051
--hostname_suffix="wallet_v1"
--v1_behavior=true
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"
wallet-v2 wallet-v2 1 --port=50051
--hostname_suffix "wallet_v2"
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"

그런 후 다음 표의 라우팅 규칙에 따라 Traffic Director가 요청을 테스트 클라이언트에서 이러한 서비스로 라우팅하도록 구성합니다.

호스트 일치 규칙 라우팅 작업
wallet.grpcwallet.io 기본값 wallet-v1
전체 경로: /grpc.examples.wallet.Wallet/FetchBalance wallet-v1: 40%
wallet-v2: 60%
경로 프리픽스: /grpc.examples.wallet.Wallet/ wallet-v2
stats.grpcwallet.io 기본값 stats
경로 프리픽스: "/"
헤더: {"membership": "premium"}
stats-premium
account.grpcwallet.io 기본값 account

로컬 환경 준비

이러한 예시에 필요한 대로 환경을 설정하려면 다음 명령어를 실행합니다.

  1. gcloud 바이너리를 업데이트하여 최신 버전이 있는지 확인합니다.

    gcloud components update
    
  2. 예시 저장소를 다운로드합니다.

    sudo apt-get install git -y
    
  3. EXAMPLES_VERSION 값을 설정하고 예시에 맞는 저장소를 클론합니다.

    export EXAMPLES_VERSION=v1.0.x
    git clone -b "${EXAMPLES_VERSION}" --single-branch --depth=1 \
      https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    

Cloud Router 인스턴스 만들기 및 구성

이 섹션에서는 각 리전에서 Cloud Router 인스턴스를 만들고 Cloud NAT에 맞게 이를 구성합니다. 이 예시에서 생성된 VM은 외부 IP 주소를 포함하지 않지만, 인터넷 액세스가 필요합니다. Cloud NAT로 Cloud Router를 구성하면 필요한 액세스가 제공됩니다.

gcloud

  1. Cloud Router 인스턴스를 만듭니다.

    gcloud compute routers create nat-router-us-central1 \
        --network=default \
        --region=us-central1
    
  2. Cloud NAT용 라우터를 구성합니다.

    gcloud compute routers nats create nat-config \
        --router-region=us-central1 \
        --router=nat-router-us-central1 \
        --nat-all-subnet-ip-ranges \
        --auto-allocate-nat-external-ips
    

gRPC 상태 확인 및 방화벽 규칙 만들기

이 섹션에서는 gRPC 상태 확인과 gRPC 상태 확인 요청이 네트워크에 도달하도록 허용하는 방화벽 규칙을 만듭니다. 나중에 gRPC 상태 확인은 백엔드 서비스와 연결되어 백엔드 서비스의 백엔드 상태를 확인합니다.

gcloud

  1. 상태 확인을 만듭니다.

    gcloud compute health-checks create grpc grpcwallet-health-check \
        --use-serving-port
    
  2. 상태 확인의 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create grpcwallet-allow-health-checks \
        --network default --action allow --direction INGRESS \
        --source-ranges 35.191.0.0/16,130.211.0.0/22 \
        --target-tags allow-health-checks \
        --rules tcp:50051-50053
    

인스턴스 템플릿 만들기

이 섹션에서는 포트 50053에 노출된 account gRPC 서비스를 배포하는 인스턴스 템플릿을 만듭니다.

gcloud

  • 인스턴스 템플릿을 만듭니다.

    gcloud compute instance-templates create grpcwallet-account-template \
       --scopes=https://www.googleapis.com/auth/cloud-platform \
       --tags=allow-health-checks \
       --network-interface=no-address \
       --image-family=debian-10 \
       --image-project=debian-cloud \
       --metadata-from-file=startup-script=<(echo "#! /bin/bash
    set -ex
    cd /root
    export HOME=/root
    sudo apt-get update -y
    sudo apt-get install -y golang git
    git clone -b ${EXAMPLES_VERSION} --single-branch --depth=1 https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/go/account_server/
    go build .
    sudo systemd-run ./account_server --port 50053 --hostname_suffix account")
    

관리형 인스턴스 그룹 만들기

관리형 인스턴스 그룹(MIG)은 필요에 따라 자동 확장을 사용하여 새 백엔드 VM을 만듭니다. 이 섹션에서는 이전 섹션에서 만든 인스턴스 템플릿을 사용하여 MIG를 만듭니다.

gcloud

  • 인스턴스 그룹을 만듭니다.

    gcloud compute instance-groups managed create grpcwallet-account-mig-us-central1 \
       --zone=us-central1-a \
       --size=2 \
       --template=grpcwallet-account-template
    

이름이 지정된 포트 구성

이 섹션에서는 gRPC 서비스에 사용될 이름이 지정된 포트를 구성합니다. 이름이 지정된 포트는 gRPC 서비스가 요청을 리슨하는 포트입니다. 이 예시에서 이름이 지정된 포트는 포트 50053입니다.

gcloud

  • 이름이 지정된 포트를 만듭니다.

    gcloud compute instance-groups set-named-ports grpcwallet-account-mig-us-central1 \
       --named-ports=grpcwallet-account-port:50053 \
       --zone=us-central1-a
    

백엔드 서비스 만들기

이 섹션에서는 부하 분산 스키마 INTERNAL_SELF_MANAGED와 프로토콜 GRPC를 사용하여 전역 백엔드 서비스를 만듭니다. 그런 다음 상태 확인 및 인스턴스 그룹을 백엔드 서비스와 연결합니다. 이 예시에서는 관리형 인스턴스 그룹 만들기에서 만든 MIG를 사용합니다. 이 MIG는 account gRPC 서비스를 실행합니다. --port-name 플래그의 포트는 이름이 지정된 포트 구성에서 만든 이름이 지정된 포트입니다.

gcloud

  1. 백엔드 서비스를 만든 후 상태 확인을 새 백엔드 서비스에 연결합니다.

    gcloud compute backend-services create grpcwallet-account-service \
        --global \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=GRPC \
        --port-name=grpcwallet-account-port \
        --health-checks=grpcwallet-health-check
    
  2. 관리형 인스턴스 그룹을 백엔드로 추가합니다.

    gcloud compute backend-services add-backend grpcwallet-account-service \
        --instance-group=grpcwallet-account-mig-us-central1 \
        --instance-group-zone=us-central1-a \
        --global
    

gRPC 월렛 예시에서 사용할 나머지 백엔드 서비스를 만드는 단계는 이전 단계와 비슷합니다. 셸 스크립트를 실행하여 나머지 서비스를 만듭니다. 스크립트는 다음 백엔드 서비스를 배포합니다.

  • stats
  • stats-premium
  • wallet-v1
  • wallet-v2

추가 백엔드 서비스를 만드는 셸 스크립트를 실행합니다.

traffic-director-grpc-examples/scripts/create_service.sh go stats 50052 stats '--account_server="xds:///account.grpcwallet.io"'

traffic-director-grpc-examples/scripts/create_service.sh go stats 50052 stats-premium '--account_server="xds:///account.grpcwallet.io" --premium_only=true'

traffic-director-grpc-examples/scripts/create_service.sh java wallet 50051 wallet-v1 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io" --v1_behavior=true'

traffic-director-grpc-examples/scripts/create_service.sh java wallet 50051 wallet-v2 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io"'

라우팅 규칙 만들기

이 섹션에서는 예시를 통해 서비스의 가상 호스트 이름과 관련 라우팅 규칙을 지정하는 URL 맵을 만듭니다. 자세한 내용은 라우팅 규칙 맵을 참조하세요.

URL 맵에서 hostRules는 예시의 서비스 가상 호스트 이름을 지정합니다. 클라이언트가 특정 서비스에 연결하도록 채널 URI에서 사용하는 이름입니다. 예를 들어 account 서비스에 요청을 보내려면 클라이언트는 채널 URI에서 xds:///account.grpcwallet.io를 사용합니다. hostRules에서 account.grpcwallet.io 값으로 hosts 항목을 구성합니다.

hosts 항목과 연결된 pathMatcher는 가상 호스트의 모든 라우팅 규칙이 포함된 pathMatcher의 이름을 지정합니다. pathMatcher 구성은 일치하는 규칙과 해당 작업 규칙으로 구성됩니다. 이 예시에서는 다음과 같이 구성됩니다.

  • 요청이 account.grpcwallet.io로 전송되면 이 요청을 grpcwallet-account-service 백엔드 서비스로 전송합니다.
  • 요청이 stats.grpcwallet.io로 전송된 경우:
    • 요청에 값이 premiummembership 헤더가 포함되어 있으면 요청을 grpcwallet-stats-premium-service 백엔드 서비스로 전송합니다.
    • 또는 기본 백엔드 서비스 grpcwallet-stats-service로 요청을 전송합니다.
  • 요청이 wallet.grpcwallet.io로 전송된 경우:

    • ServiceName 또는 MethodName/grpc.examples.wallet.Wallet/FetchBalance와 일치하면 해당 요청의 40%를 grpcwallet-wallet-v2-service 백엔드 서비스로 전송하고 나머지 요청을 grpcwallet-wallet-v1-service 백엔드 서비스로 전송합니다.
    • 그렇지 않고 ServiceName/grpc.examples.wallet.Wallet/과 일치하면 호출된 메서드와 관계없이 요청을 grpcwallet-wallet-v1-service 백엔드 서비스로 전송합니다.

gcloud

URL 맵을 만듭니다.

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')

gcloud compute url-maps import grpcwallet-url-map << EOF
defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
name: grpcwallet-url-map

hostRules:
- hosts:
  - account.grpcwallet.io
  pathMatcher: grpcwallet-account-path-matcher
- hosts:
  - stats.grpcwallet.io
  pathMatcher: grpcwallet-stats-path-matcher
- hosts:
  - wallet.grpcwallet.io
  pathMatcher: grpcwallet-wallet-path-matcher

pathMatchers:
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
  name: grpcwallet-account-path-matcher

- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-service
  name: grpcwallet-stats-path-matcher
  routeRules:
  - matchRules:
    - prefixMatch: /
      headerMatches:
      - headerName: membership
        exactMatch: premium
    priority: 0
    service: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-premium-service

- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
  name: grpcwallet-wallet-path-matcher
  routeRules:
  - matchRules:
    - prefixMatch: /
      headerMatches:
      - headerName: route
        exactMatch: timeout
    priority: 0
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 100
      maxStreamDuration:
        seconds: 5

  - matchRules:
    - prefixMatch: /
      headerMatches:
      - headerName: route
        exactMatch: fault
    priority: 1
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 100
      faultInjectionPolicy:
        abort:
          httpStatus: 503
          percentage: 50

  - matchRules:
    - fullPathMatch: /grpc.examples.wallet.Wallet/FetchBalance
    priority: 2
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 40
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
        weight: 60

  - matchRules:
    - prefixMatch: /grpc.examples.wallet.Wallet/
    priority: 3
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 100
EOF

대상 프록시 및 전달 규칙 만들기

이 섹션에서는 대상 gRPC 프록시와 전달 규칙을 만듭니다.

대상 gRPC 프록시는 이전 단계에서 만든 URL 맵을 참조합니다. --validate-for-proxyless 플래그를 지정하면 프록시리스 gRPC 배포와 호환되지 않는 기능이 우발적으로 사용 설정되지 않도록 구성 확인을 사용 설정할 수 있습니다.

gcloud

  • 대상 gRPC 프록시를 만듭니다.

    gcloud compute target-grpc-proxies create grpcwallet-proxy \
       --url-map=grpcwallet-url-map \
       --validate-for-proxyless
    

전달 규칙은 생성된 대상 gRPC 프록시를 참조합니다. 부하 분산 스키마가 INTERNAL_SELF_MANAGED로 설정되어 이 전달 규칙이 Traffic Director에서 사용됨을 나타냅니다. 전역 전달 규칙이어야 합니다. IP 주소는 0.0.0.0으로 설정됩니다. 프록시리스 gRPC 클라이언트가 DNS를 조회하는 대신 LDS 요청을 Traffic Director로 전송하여 대상 URI의 hostname:port를 확인하기 때문입니다. 자세한 내용은 이름 확인 스키마를 참조하세요.

대상 URI에 포트가 지정되어 있지 않으면 기본값은 80입니다. 예를 들어 대상 URI xds:///foo.myservice:8080은 포트 8080으로 구성된 전달 규칙과 일치합니다. 이 예시에서 전달 규칙은 포트 80으로 구성됩니다.

gcloud

  • 방화벽 규칙을 만듭니다.

    gcloud compute forwarding-rules create grpcwallet-forwarding-rule \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --address=0.0.0.0 \
       --address-region=us-central1 \
       --target-grpc-proxy=grpcwallet-proxy \
       --ports=80 \
       --network=default
    

구성 확인

구성 프로세스가 완료되면 Google Cloud Console의 Traffic Director 페이지를 확인하여 구성한 백엔드 서비스를 사용할 수 있는지 확인합니다. 백엔드 서비스와 관련 백엔드가 정상으로 보고되었는지 확인합니다.

라우팅 구성 확인

이 섹션에서는 라우팅 구성이 올바르게 작동하는지 확인합니다. grpcurl 도구를 사용하여 구성을 테스트합니다.

gcloud

  1. 클라이언트를 실행할 클라이언트 VM을 만들어 서비스를 테스트합니다. 선택적으로 --network-interface=no-address 플래그를 포함할 수 있습니다.

    gcloud compute instances create grpc-wallet-client \
        --zone=us-central1-a \
        --scopes=https://www.googleapis.com/auth/cloud-platform \
        --image-family=debian-10 \
        --image-project=debian-cloud \
        --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -e
    export GRPC_XDS_BOOTSTRAP=/run/td-grpc-bootstrap.json
    # Expose bootstrap variable to SSH connections
    echo export GRPC_XDS_BOOTSTRAP=$GRPC_XDS_BOOTSTRAP | sudo tee /etc/profile.d/grpc-xds-bootstrap.sh
    # Create the bootstrap file
    curl -L https://storage.googleapis.com/traffic-director/td-grpc-bootstrap-0.11.0.tar.gz | tar -xz
    ./td-grpc-bootstrap-0.11.0/td-grpc-bootstrap | sudo tee $GRPC_XDS_BOOTSTRAP')
    
  2. SSH를 사용하여 VM에 액세스하고 다음 명령어를 실행하여 VM을 준비합니다.

    export EXAMPLES_VERSION=v1.0.x
    sudo apt-get update
    sudo apt-get install git -y
    
  3. 다음 명령어를 실행합니다.

    git clone -b "${EXAMPLES_VERSION}" --single-branch --depth=1 \
       https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.6.1/grpcurl_1.6.1_linux_x86_64.tar.gz | tar -xz
    chmod +x grpcurl
    

사이드카 프록시 없이 서비스에 액세스하려면 gRPC 클라이언트에서 xds 이름 확인 스킴을 사용해야 합니다. 이 스키마는 클라이언트에서 사용되는 gRPC 라이브러리에 xDS 서버를 사용하여 호스트 이름을 확인하도록 지시합니다. 이렇게 하려면 부트스트랩 구성이 필요합니다.

이전 섹션의 시작 스크립트는 GRPC_XDS_BOOTSTRAP 환경 변수를 설정하고 도우미 스크립트를 사용하여 부트스트랩 파일을 생성합니다. Compute Engine VM 인스턴스에 대한 이러한 세부정보를 알고 있는 메타데이터 서버에서 생성된 부트스트랩 파일에 있는 TRAFFICDIRECTOR_GCP_PROJECT_NUMBER, TRAFFICDIRECTOR_NETWORK_NAME, 영역의 값을 가져옵니다. -gcp-project-number 옵션과 -vpc-network-name 옵션을 사용하여 이러한 값을 도우미 스크립트에 수동으로 제공할 수 있습니다.

grpcurl 도구를 사용하여 구성 확인

SSH 셸에서 다음 명령어를 실행하여 wallet-service, stats-service, account-service가 실행 중인지 확인합니다.

./grpcurl -plaintext xds:///account.grpcwallet.io list
./grpcurl -plaintext -d '{"token": "2bd806c9"}' xds:///account.grpcwallet.io grpc.examples.wallet.account.Account/GetUserInfo
./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' xds:///stats.grpcwallet.io grpc.examples.wallet.stats.Stats/FetchPrice
./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' -d '{"include_balance_per_address": true}' xds:///wallet.grpcwallet.io grpc.examples.wallet.Wallet/FetchBalance

다음과 같은 결과가 표시됩니다.

grpc.examples.wallet.account.Account
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection

{
  "name": "Alice",
  "membership": "PREMIUM"
}

{
  "price": "10295"
}

{
  "balance": "5089953"
}

grpc-wallet 클라이언트로 확인

다음 언어별 안내를 따라 구성을 확인합니다. 이 명령어는 URL 맵의 일치 규칙에 따라 요청이 백엔드 서비스로 라우팅됨을 보여주기 위해 추가 메타데이터와 함께 RPC 여러 개를 전송합니다. 또한 이 명령어는 각 응답의 백엔드 호스트 이름을 출력하여 요청이 라우팅된 백엔드 서비스를 보여줍니다.

자바

  1. gRPC 자바 클라이언트에서 서비스를 확인하려면 다음을 실행합니다.

    sudo apt-get install -y openjdk-11-jdk-headless
    
  2. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/java
    ./gradlew installDist
    
    # This command calls 'FetchBalance' from 'wallet-service' in a loop,
    # to demonstrate that 'FetchBalance' gets responses from 'wallet-v1' (40%)
    # and 'wallet-v2' (60%).
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC 'WatchBalance' from 'wallet-service'.
    # The RPC path matches the service prefix, so all requests are
    # sent to 'wallet-v2'.
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls 'WatchPrice' from 'stats-service'. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to 'stats-premium' and get faster responses. Alice's requests
    # always go to premium and Bob's go to regular.
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

Go

  1. gRPC Go 클라이언트에서 서비스를 확인하려면 다음을 실행합니다.

    sudo apt install -y golang
    
  2. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/go/wallet_client
    go build
    
    # This command calls 'FetchBalance' from 'wallet-service' in a loop,
    # to demonstrate that 'FetchBalance' gets responses from 'wallet-v1' (40%)
    # and 'wallet-v2' (60%).
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch
    
    # This command calls the streaming RPC 'WatchBalance' from 'wallet-service'.
    # The RPC path matches the service prefix, so all requests
    # are sent to 'wallet-v2'.
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch
    
    # This command calls 'WatchPrice' from 'stats-service'. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to 'stats-premium' and get faster responses. Alice's requests
    # always go to premium and Bob's go to regular.
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Bob
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Alice
    

C++

  1. gRPC C++ 클라이언트에서 서비스를 확인하려면 다음을 실행합니다.

    sudo apt-get install -y build-essential
    
  2. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/cpp
    ../tools/bazel build :client
    
    # This command calls 'FetchBalance' from 'wallet-service' in a loop, to demonstrate that
    # 'FetchBalance' gets responses from 'wallet-v1' (40%) and 'wallet-v2' (60%).
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC 'WatchBalance'  from 'wallet-service'.
    # The RPC path matches the service prefix, so all requests are sent to 'wallet-v2'.
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls 'WatchPrice' from 'stats-service'. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to 'stats-premium' and get faster responses. Alice's requests
    # always go to premium, and Bob's go to regular.
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

고급 옵션 구성

다음 섹션의 안내에 따라 고급 트래픽 라우팅 옵션을 추가로 구성할 수 있습니다.

회로 차단

회로 차단을 통해 클라이언트 요청으로 인해 백엔드에 과부하가 발생하지 않도록 장애 임곗값을 설정할 수 있습니다. 요청이 설정한 한도에 도달하면 클라이언트가 추가 요청 전송을 중지하여, 백엔드를 복구할 시간을 줍니다.

회로 차단은 백엔드에 과부하를 발생시키지 않고 클라이언트에 오류를 반환하여 연쇄적 장애를 방지합니다. 이렇게 하면 일부 트래픽을 제공하면서도 자동 확장을 통해 용량을 늘려 트래픽 급증을 처리하는 것과 같은 과부하 상황 관리를 위한 시간을 확보할 수 있습니다.

stats-service의 백엔드 서비스를 만들 때 create_service.sh 스크립트는 구성에 다음 줄을 포함합니다.

circuitBreakers:
  maxRequests: 1

이 설정은 클라이언트에서 stats-service에 대해 대기 중인 요청을 한 번에 한 개로 제한합니다. wallet-v2 서비스가 1개만 있기 때문에 2개의 동시 월렛 클라이언트 WatchBalance 작업을 실행하면 두 번째 인스턴스에서 오류가 표시됩니다.

자바

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/java
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob  2>/dev/null 1>/dev/null &
    
    sleep 10 # Wait a few seconds to allow the watch to begin.
    
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob
    
  2. 출력은 다음과 같이 표시됩니다.

    io.grpc.examples.wallet.Client run
    INFO: Will try to run balance
    io.grpc.examples.wallet.Client run
    WARNING: RPC failed: Status{code=INTERNAL, description=RPC to stats server failed: UNAVAILABLE: Cluster max concurrent requests limit exceeded, cause=null}
    
  3. kill 명령어를 실행합니다.

    kill %%
    

Go

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/go
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch --user=Bob 2> /dev/null 1> /dev/null &
    
    sleep 10 # Wait a few seconds to allow the watch to begin.
    
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch --user=Bob
    
  2. 출력은 다음과 같이 표시됩니다.

    server host: error: no hostname
    failed to fetch balance: rpc error: code = Internal desc = RPC to stats server failed:
    UNAVAILABLE: Cluster max concurrent requests limit exceeded
    
  3. kill 명령어를 실행합니다.

    kill %%
    

C++

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/cpp
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob 2>/dev/null 1>/dev/null &
    
    sleep 10 # Wait a few seconds to allow the watch to begin.
    
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob
    
  2. 출력은 다음과 같이 표시됩니다.

    Client arguments: command: balance, wallet_server: xds:///wallet.grpcwallet.io, stats_server:
    localhost:18882, user: Bob, watch: 1 ,unary_watch: 0, observability_project: , route:
    14: Cluster max concurrent requests limit exceeded
    
  3. kill 명령어를 실행합니다.

    kill %%
    

결함 주입

결함 주입은 높은 지연 시간, 서비스 과부하, 서비스 장애, 네트워크 파티션 나누기 등의 장애를 시뮬레이션하는 요청을 제공할 때 의도적으로 오류를 발생시킬 수 있습니다. 이 기능은 장애를 시뮬레이션하면서 서비스의 복원력을 테스트하는 데 유용합니다.

이전에 URL 맵을 만든 경우 route=fault 헤더를 사용하여 wallet-service에 50% 비율의 결함 주입을 설정합니다.

결함 주입을 표시하기 위해 다음 언어의 코드를 사용합니다.

자바

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/java
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true --user=Bob --route=fault
    
  2. 출력은 다음과 같이 표시됩니다.

    server host: grpcwallet-wallet-v2-mig-us-central1-zznc
    total balance: 10340491
    - address: 148de9c5, balance: 2549839
    - address: 2e7d2c03, balance: 7790652
    io.grpc.examples.wallet.Client run
    WARNING: RPC failed: Status{code=UNAVAILABLE, description=HTTP status code 503, cause=null}
    

Go

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/go
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch --user=Bob --route=fault
    
  2. 출력은 다음과 같이 표시됩니다.

     server host: grpcwallet-wallet-v1-mig-us-central1-bm1t_wallet-v1
     user: Bob, total grpc-coin balance: 10452589.
      - address: 2e7d2c03, balance: 7875108.
      - address: 148de9c5, balance: 2577481.
     failed to fetch balance: rpc error: code = Unavailable desc = RPC terminated due to fault injection
    

C++

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/cpp
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true --user=Bob --route=fault
    
  2. 출력은 다음과 같이 표시됩니다.

    Client arguments: command: balance, wallet_server: xds:///wallet.grpcwallet.io, stats_server:                 localhost:18882, user: Bob, watch: 0 ,unary_watch: 1, observability_project: , route: fault
    server host: grpcwallet-wallet-v2-mig-us-central1-1lm6
    user: Bob total grpc-coin balance: 10211908
     - address: 148de9c5, balance: 2518132
     - address: 2e7d2c03, balance: 7693776
    14: Fault injected
    

최대 스트림 지속 시간

최대 스트림 지속 시간은 최대 제한 시간이 모든 RPC에 적용되도록 합니다. 이렇게 하면 마감 시한 설정을 잊었거나 과도하게 설정한 클라이언트가 서버 리소스를 낭비하지 못하도록 방지합니다.

이전에 URL 맵을 만든 경우 route=timeout 헤더를 사용하여 wallet-service에 RPC의 최대 스트림 기간을 5초로 설정합니다.

시간 제한을 보여주기 위해 먼저 wallet-v2 서비스를 중지합니다.

gcloud

gcloud compute instance-groups managed resize \
    --size=0 grpcwallet-wallet-v2-mig-us-central1 \
    --zone=us-central1-a

이를 처리할 수 있는 백엔드 서비스가 없고, 애플리케이션에 마감 시간이 설정되지 않기 때문에 일반 watch 명령어가 계속 막힌 상태로 유지됩니다.

자바

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/java
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob
    
  2. 명령어가 응답하지 않습니다. ^C를 눌러 명령어를 중단합니다.

Go

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/go
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch --user=Bob
    
  2. 명령어가 응답하지 않습니다. ^C를 눌러 명령어를 중단합니다.

C++

  1. 다음 명령어를 실행합니다.

    cd ~/traffic-director-grpc-examples/cpp
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob
    
  2. 명령어가 응답하지 않습니다. ^C를 눌러 명령어를 중단합니다.

하지만 timeout 경로를 사용할 때는 maxStreamDuration 설정으로 인해 5초 후 감시가 실패합니다.

자바

  1. 다음 명령어를 실행합니다.

    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob --route=timeout
    
  2. 출력은 다음과 같이 표시됩니다.

    io.grpc.examples.wallet.Client run
    WARNING: RPC failed: Status{code=DEADLINE_EXCEEDED, description=deadline exceeded after 4.999594070s.         [wait_for_ready, buffered_nanos=5000553401, waiting_for_connection], cause=null}
    

Go

  1. 다음 명령어를 실행합니다.

    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch --user=Bob --route=timeout
    
  2. 출력은 다음과 같이 표시됩니다.

    failed to create stream: rpc error: code = DeadlineExceeded desc = context deadline exceeded.
    

C++

  1. 다음 명령어를 실행합니다.

    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob --route=timeout
    
  2. 출력은 다음과 같이 표시됩니다.

    Client arguments: command: balance, wallet_server: xds:///wallet.grpcwallet.io, stats_server:
    localhost:18882, user: Bob, watch: 1 ,unary_watch: 0, observability_project: , route: timeout
    4: Deadline Exceeded
    

리소스 삭제

리소스를 삭제하려면 로컬 시스템에서 다음 명령어를 실행합니다.

traffic-director-grpc-examples/scripts/cleanup.sh

다음 단계