通过高级流量管理设置无代理 gRPC 服务

本文档提供了有关使用以下路由功能配置 Traffic Director 的端到端说明:

  • 路由匹配
  • 流量拆分
  • 熔断
  • 故障注入
  • 流时长上限

虽然本文档重点介绍如何在 Compute Engine 上使用无代理 gRPC 设置高级流量管理,但在 Google Kubernetes Engine 上使用无代理 gRPC 时也支持高级流量管理。

准备工作

在开始之前,请务必查看准备使用无代理 gRPC 服务设置 Traffic Director 中的要求。除非满足所有要求,否则无法配置高级流量管理。

如需了解有关这些功能的概念信息,请参阅高级流量管理

关于 gRPC Wallet 示例

为了说明这些功能,您将部署一个 gRPC Wallet 示例。如下图所示,您将为 wallet-servicestats-serviceaccount-service 创建后端服务。

gRPC Wallet 流量路由配置示例(点击可放大)
gRPC Wallet 流量路由配置示例(点击可放大)

在此示例中,您将部署每项服务的多个版本,以根据您所配置的规则说明请求路由。为了模拟服务的不同版本的构建和部署,您将使用服务器标志来更改仅构建一次的二进制文件的行为。

  • --port 标志指定后端虚拟机上的服务侦听的端口。
  • --hostname_suffix 标志指定附加到响应请求的虚拟机主机名的值。结果值将作为 hostname 元数据添加到响应中。这有助于您确定后端服务的哪个实例响应了客户端请求。
  • 值为 true--premium_only 标志指定该服务是 stats 服务的高级版本。
  • 值为 true--v1_behavior 标志指定 Wallet 二进制文件充当 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

准备本地环境

如需根据这些示例的要求设置环境,请运行以下命令:

# Update the gcloud binary to ensure you have the latest version.
gcloud components update

# Download the examples repo.
sudo apt-get install git -y

运行以下命令:

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 配置这些实例。此示例创建的虚拟机没有外部 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

  1. 创建实例模板。

    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")
    

创建代管实例组

代管实例组会根据需要使用自动扩缩功能创建新的后端虚拟机。在本部分中,您将使用在上一部分中创建的实例模板创建代管实例组。

gcloud

  1. 创建实例组。

    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

  1. 创建已命名端口。

    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,然后将运行状况检查和实例组与后端服务相关联。在此示例中,您将使用在创建代管实例组中创建的代管实例组。此代管实例组运行 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 Wallet 示例中使用的其余后端服务的步骤与上述步骤类似。您可以通过运行 Shell 脚本来创建其余服务。该脚本会部署以下后端服务:

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

运行创建额外后端服务的 Shell 脚本:

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"'

创建路由规则

在本部分中,您将创建一个网址映射,用于指定此示例中服务的虚拟主机名以及关联的路由规则。如需了解详情,请参阅路由规则映射

在网址映射中,hostRules 指定示例中服务的虚拟主机名。这些是客户端在通道 URI 中用于连接到特定服务的名称。例如,为了向 account 服务发送请求,客户端会在通道 URI 中使用 xds:///account.grpcwallet.io。您必须在 hostRules 中配置一个值为 account.grpcwallet.iohosts 条目。

hosts 条目关联的 pathMatcher 指定包含该虚拟主机的所有路由规则的 pathMatcher 的名称。pathMatcher 配置由匹配规则和相应的操作规则组成。该示例会生成以下配置:

  • 当某个请求发送到 account.grpcwallet.io 时,将该请求发送到 grpcwallet-account-service 后端服务。
  • 当某个请求发送到 stats.grpcwallet.io 时:
    • 如果该请求包含值为 premium 的标头 membership,则将该请求发送到 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

运行以下命令以创建网址映射:

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 代理会引用您在上一步中创建的网址映射。--validate-for-proxyless 标志会启用配置检查,这样您就不会在无意中启用与无代理 gRPC 部署不兼容的功能。

gcloud

  1. 创建目标 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 客户端通过向 Traffic Director 发送 LDS 请求(而不是执行 DNS 查找)来解析目标 URI 中的 hostname:port。如需了解详情,请参阅名称解析方案

如果目标 URI 中未指定端口,则默认值为 80。例如,目标 URI xds:///foo.myservice:8080 与使用端口 8080 配置的转发规则匹配。在此示例中,转发规则是使用端口 80 进行配置的。

gcloud

  1. 创建转发规则。

    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
    

验证配置

配置过程完成后,请通过检查控制台中的 Traffic Director 页面来验证您配置的后端服务是否可用。请确认后端服务和关联的后端报告为运行状况良好。

验证路由配置

在本部分中,您将验证路由配置是否正常工作。您可以使用 grpcurl 工具测试配置。

gcloud

  1. 创建客户端虚拟机,用于运行客户端以测试服务。 您可以选择性添加 --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 访问虚拟机,然后运行以下命令来准备虚拟机:

    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
    

为了在没有 Sidecar 代理的情况下访问服务,gRPC 客户端需要使用 xds 名称解析方案。此方案指示客户端所用的 gRPC 库使用 xDS 服务器来解析主机名。为此,您需要用到引导配置。上一部分中的启动脚本会设置 GRPC_XDS_BOOTSTRAP 环境变量,并使用帮助程序脚本生成引导文件。所生成引导文件中 TRAFFICDIRECTOR_GCP_PROJECT_NUMBERTRAFFICDIRECTOR_NETWORK_NAME 和 zone 的值将从知道 Compute Engine 虚拟机实例这些详细信息的元数据服务器获取。您可以使用 -gcp-project-number-vpc-network-name 选项手动将这些值提供给帮助程序脚本。

使用 grpcurl 工具验证配置

在 SSH shell 中运行以下命令,验证 AccountStatsWallet 服务是否正在运行。

./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 客户端进行验证

使用以下特定于语言的说明来验证配置。以下命令会发送多个 RPC(一些 RPC 具有额外的元数据),以显示系统根据网址映射中的匹配规则将请求路由到后端服务。以下命令还会输出每个响应的后端主机名,以显示请求所路由到的后端服务。

Java

  1. 如需使用 gRPC Java 客户端验证服务,请运行以下命令:

    sudo apt-get install -y openjdk-11-jdk-headless
    
  2. 运行以下命令:

    cd ~/traffic-director-grpc-examples/java
    ./gradlew installDist
    
    # This command calls FetchBalance from the 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 the 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 the 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 goes 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 the 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 the 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 the 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 goes 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 the 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 the 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 the 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 goes 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
    

配置更多高级选项

您可以按照以下部分中的说明配置其他高级流量路由选项。

熔断

通过熔断功能,您可以设置失败阈值以防止客户端请求导致后端过载。在请求达到您设置的上限后,客户端会停止发送更多请求,从而为您的后端留出恢复时间。

熔断会通过向客户端返回错误而不是让后端过载来防止级联故障。这样一来,您便可处理一些流量,同时为管理过载情况提供时间,例如通过自动扩缩来增加容量以应对流量高峰。

在为统计信息服务创建后端服务时,create_service.sh 脚本在其配置中包含以下行:

circuitBreakers:
  maxRequests: 1

此设置会将客户端限制为一次向统计信息服务发出一个待处理的请求。由于只有一项 wallet-v2 服务,因此运行两个并发 Wallet 客户端 WatchBalance 操作会在第二个实例中失败。

Java

  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 above 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 above 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 above 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 %%
    

故障注入

在处理请求时故障注入会引入错误,以此模拟高延迟、服务过载、服务故障和网络分区等故障。在测试服务对模拟故障的弹性时,这项功能会非常有用。

创建上述网址映射后,将通过 route=fault 标头为 Wallet 服务设置 50% 的故障注入率。

如需演示故障注入,请使用以下语言的代码。

Java

  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。这样可防止忘记设置截止时间或设置过度截止时间的客户端浪费服务器资源。

创建上述网址映射后,将通过 route=timeout 标头为 Wallet 服务的 RPC 设置 5 秒的流时长上限。

如需演示超时,我们首先停止 wallet-v2 服务。

gcloud

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

常规 watch 命令会永久卡住,因为没有后端服务来处理它,并且应用未设置截止时间:

Java

  1. 运行以下命令:

    cd ~/traffic-director-grpc-examples/java
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob
    
    1. 此命令停止响应。按 ^C 可中断此命令。

Go

  1. 运行以下命令:

    cd ~/traffic-director-grpc-examples/go
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch --user=Bob
    
    1. 此命令停止响应。按 ^C 可中断此命令。

C++

  1. 运行以下命令:

    cd ~/traffic-director-grpc-examples/cpp
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true --user=Bob
    
    1. 此命令停止响应。按 ^C 可中断此命令。

不过,使用 timeout 路由时,手表会在 5 秒后因 maxStreamDuration 设置而失败:

Java

  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

后续步骤

如果您在配置过程中遇到意外行为,请参阅排查无代理 Traffic Director 部署问题以及无代理 gRPC 应用的 Traffic Director 限制