为全球外部应用负载均衡器设置流量管理

本文档展示了针对某些特定用例使用流量管理的示例。许多其他用例也是可行的。

本文档包含全球外部应用负载均衡器的示例。全球外部应用负载均衡器使用 EXTERNAL_MANAGED 负载均衡方案和全球负载均衡组件,例如转发规则、网址映射和后端服务。

如需了解如何使用传统应用负载均衡器进行流量管理,请参阅传统应用负载均衡器的流量管理概览

如需了解如何使用区域级外部应用负载均衡器进行流量管理,请参阅区域级外部应用负载均衡器的流量管理概览

除了本页面介绍的高级路由功能之外,受支持的应用负载平衡器还与 Service Extensions 集成,可让您将自定义逻辑插入负载均衡数据路径中。

准备工作

请务必了解流量管理的工作原理。 如需了解详情,请参阅全球外部应用负载均衡器的流量管理概览

配置和测试流量管理

在所选的配置环境中,您可以使用 YAML 配置来设置流量管理。网址映射和后端服务都有自己的 YAML 文件。根据所选功能,您需要编写网址映射 YAML 文件和/或后端服务 YAML 文件。

如果在编写这些 YAML 文件时需要帮助,您可以使用本页面中的示例以及 Cloud Load Balancing API 文档。

Google Cloud 控制台不受支持。

全局网址映射 API全局后端服务 API 文档提供了一系列完整的字段,包括关于关系、限制和基数的语义。

您可以将配置测试添加到网址映射,以确保您的网址映射按预期路由请求。您可以试验不同的网址映射规则,并根据需要运行任意数量的测试,以确保该映射将流量路由到相应的后端服务或后端存储桶。如需了解详情,请参阅将测试添加到网址映射。如果您想测试对网址映射的新更改而无需实际部署该映射,请参阅验证网址映射配置

将流量映射到单项服务

将所有流量发送到单个服务。请务必替换占位符。

    defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
    hostRules:
    - hosts:
      - '*'
      pathMatcher: matcher1
    name: URL_MAP_NAME
    pathMatchers:
    - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
      name: matcher1
      routeRules:
      - matchRules:
        - prefixMatch: /PREFIX
        priority: PRIORITY  # 0 is highest
        routeAction:
          weightedBackendServices:
          - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
            weight: 100

在两项服务之间拆分流量

在两项服务之间或多项服务之间拆分流量。请务必替换占位符。

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   name: URL_MAP_NAME
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
     - matchRules:
       - prefixMatch: /PREFIX
       priority: 2
       routeAction:
         weightedBackendServices:
         - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
           weight: 95
         - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_2
           weight: 5

配置网址重定向

以下示例会返回可配置的 301 MOVED_PERMANENTLY_DEFAULT 响应代码。此外,它还会使用适当的 URI 设置 Location 响应标头,并替换重定向操作中所指定的主机和路径。

如需为后端存储桶创建重定向,请为 defaultService 字段使用 projects/PROJECT_ID/global/backendBuckets/BACKEND_BUCKET

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: <var>URL_MAP_NAME</var>
   hostRules:
   - hosts:
     - "HOST TO REDIRECT FROM" # Use * for all hosts
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     defaultUrlRedirect:
       hostRedirect: "HOST TO REDIRECT TO" # Omit to keep the requested host
       pathRedirect: "PATH TO REDIRECT TO" # Omit to keep the requested path
       redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
       stripQuery: True

镜像流量

除了将请求转发到选定的后端服务,您还可以以“即发即弃”的方式将相同请求发送到配置的镜像后端服务。这意味着,负载均衡器不会等待作为镜像请求发送目标的后端的响应。请求镜像有助于测试后端服务的新版本。此外,镜像还可用于调试后端服务调试版本的生产错误(而非生产版本的错误)。

默认情况下,镜像后端服务会收到所有请求,即使原始流量在多个加权后端服务之间拆分也是如此。您可以配置镜像后端服务,使其仅接收一定百分比的请求,方法是使用可选的 mirrorPercent 标志指定要镜像的请求百分比(表示为介于 0 到 100.0 之间的值)。基于百分比的请求镜像功能目前处于预览版阶段。

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
               weight: 100
           requestMirrorPolicy:
             backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_2
             mirrorPercent: 50.0

如果您有多个加权后端服务,并且想要记录用于传送原始请求的后端服务,则可以向所有请求添加包含此信息的自定义标头。以下示例对所有客户端请求添加了名为 x-weighted-picked-backend 的自定义标头。对于标头值,请使用传送原始请求的后端服务的名称。

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
            - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
              weight: 95
              headerAction:
                requestHeadersToAdd:
                - headerName: x-weighted-picked-backend
                  headerValue: BACKEND_SERVICE_1
                  replace: True
            - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_2
              weight: 5
              headerAction:
                requestHeadersToAdd:
                - headerName: x-weighted-picked-backend
                  headerValue: BACKEND_SERVICE_2
                  replace: True
           requestMirrorPolicy:
             backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_3

使用流量镜像时,请注意以下限制:

  • 如果两项后端服务都具有托管式实例组、区域 NEG 或混合 NEG 后端,则支持流量镜像。互联网 NEG、无服务器 NEG 和 Private Service Connect 后端不支持此功能。
  • 对镜像后端服务的请求不会为 Cloud Logging 和 Cloud Monitoring 生成任何日志或指标。

重写请求的网址

在将请求发送到选定的后端服务之前,重写网址的主机名部分和/或网址的路径部分。请务必替换占位符。

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
               weight: 100
           urlRewrite:
             hostRewrite: "new-host-name.com" # Omit to keep the requested host
             pathPrefixRewrite: "/new-path/" # Omit to keep the requested path

重试请求

配置负载均衡器重试失败请求的条件、负载均衡器在重试前等待的时间以及允许的最大重试次数。

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
               weight: 100
           retryPolicy:
             retryConditions: 502, 504
             numRetries: 3
             perTryTimeout:
               seconds: 1
               nanos: 500000000

指定路由超时时间

指定选定路由的超时时间。超时是根据从请求完全处理到响应完全处理的时间计算得出的。超时包括所有重试。请务必替换占位符。

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
               weight: 100
           timeout:
             seconds: 30
             nanos: 0

配置故障注入

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

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
               weight: 100
           faultInjectionPolicy:
             delay:
               fixedDelay:
                 seconds: 10
                 nanos: 0
               percentage: 25
             abort:
               httpStatus: 503
               percentage: 50

配置 CORS

配置跨域资源共享 (CORS) 政策以处理用于强制执行 CORS 请求的设置。

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
               weight: 100
           corsPolicy:
               allowOrigins: [ "http://my-domain.com" ]
               allowMethods: [ "GET", "POST" ]
               allowHeaders: [ "Authorization", "Content-Type" ]
               maxAge: 1200
               allowCredentials: true

添加和移除请求和响应标头

在将请求发送到后端服务之前添加和移除请求标头。此外,在收到来自后端服务的响应后添加和移除响应标头。

headerNameheaderValue 的有效值存在限制。 如需了解详情,请参阅自定义标头的工作原理

   defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
   name: global-lb-map
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY  # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
               headerAction:
                 requestHeadersToAdd:
                 - headerName: header-1-name
                   headerValue: header-1-value
                   replace: True
                 requestHeadersToRemove:
                 - header-2-name
                 - header-3-name
                 responseHeadersToAdd:
                 - headerName: header-4-name
                   headerValue: header-4-value
                   replace: True
                responseHeadersToRemove:
                - header-5-name
                - header-6-name

配置离群值检测

指定从 NEG 中逐出运行状况不佳的后端虚拟机或端点的条件,以及将后端或端点视为运行状况良好、足以再次接收流量的条件。请务必替换占位符。

    loadBalancingScheme: EXTERNAL_MANAGED
    localityLbPolicy: RANDOM
    name: projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
    outlierDetection:
      baseEjectionTime:
        nanos: 0
        seconds: 30
      consecutiveErrors: 5
      consecutiveGatewayFailure: 3
      enforcingConsecutiveErrors: 2
      enforcingConsecutiveGatewayFailure: 100
      enforcingSuccessRate: 100
      interval:
        nanos: 0
        seconds: 1
      maxEjectionPercent: 50
      successRateMinimumHosts: 5
      successRateRequestVolume: 100
      successRateStdevFactor: 1900

设置流量拆分:详细步骤

本示例演示了以下步骤:

  1. 为不同服务创建不同模板。

  2. 为这些模板创建实例组。

  3. 创建路由规则以设置 95%/5% 流量拆分比例。

  4. 发送 curl 命令,表明流量拆分百分比与配置大致匹配。

此处的说明假定您采用如下设置:

  • 已创建目标代理和转发规则以及名为 global-lb-map 的网址映射。

  • 网址映射会将所有流量发送到一项名为 red-service 的后端服务,这是默认后端服务。

  • 将替代路径设置为分别向 blue-servicegreen-service 发送 5% 和 95% 的流量。

  • 使用了路径匹配器。

  • 您使用的是 Cloud Shell 或安装了 bash 的其他环境。

定义服务

以下 bash 函数可创建后端服务,包括实例模板和托管式实例组。

以下说明假定已创建 HTTP 健康检查 (global-lb-basic-check)。如需查看相关说明,请参阅以下页面之一:

function make_service() {
  local name="$1"
  local region="$2"
  local zone="$3"
  local network="$4"
  local subnet="$5"
  local subdir="$6"

  www_dir="/var/www/html/$subdir"

  (set -x; \
  gcloud compute instance-templates create "${name}-template" \
    --region="$region" \
    --network="$network" \
    --subnet="$subnet" \
    --tags=allow-ssh,load-balanced-backend \
    --image-family=debian-12 \
    --image-project=debian-cloud \
    --metadata=startup-script="#! /bin/bash
  apt-get update
  apt-get install apache2 -y
  a2ensite default-ssl
  a2enmod ssl
  sudo mkdir -p $www_dir
  /bin/hostname | sudo tee ${www_dir}index.html
  systemctl restart apache2"; \
  gcloud compute instance-groups managed create \
    "${name}-instance-group" \
    --zone="$zone" \
    --size=2 \
    --template="${name}-template"; \
  gcloud compute backend-services create "${name}-service" \
    --load-balancing-scheme=EXTERNAL_MANAGED \
    --protocol=HTTP \
    --health-checks=global-lb-basic-check \
    --global \
  gcloud compute backend-services add-backend "${name}-service" \
    --balancing-mode='UTILIZATION' \
    --instance-group="${name}-instance-group" \
    --instance-group-zone="$zone" \
    --global)
}

创建服务

调用该函数来创建三项服务,即 redgreenbluered 服务充当对 / 的请求的默认服务。greenblue 服务均在 /prefix 上设置,分别用于处理 95% 和 5% 的流量。

make_service red us-west1 us-west1-a lb-network backend-subnet ""
make_service green us-west1 us-west1-a lb-network backend-subnet /prefix
make_service blue us-west1 us-west1-a lb-network backend-subnet /prefix

创建网址映射

控制台

  1. 转到 Google Cloud 控制台中的负载均衡页面。
    转到“负载均衡”
  2. 点击 global-lb-map 链接。
  3. 点击修改

配置新路由规则

  1. 路由规则下,选择高级主机、路径和路由规则
  2. 新主机和路径匹配器下,将服务设置为 red-service,以创建默认操作。
  3. 点击完成
  4. 点击添加主机和路径匹配器
  5. 主机字段中,输入负载均衡器的转发规则的 IP 地址。
  6. 将以下 YAML 内容粘贴到路径匹配器框中:

    defaultService: projects/PROJECT_ID/global/backendServices/red-service
    name: matcher1
    routeRules:
    - priority: 2
      matchRules:
        - prefixMatch: /PREFIX
      routeAction:
        weightedBackendServices:
          - backendService: projects/PROJECT_ID/global/backendServices/green-service
            weight: 95
          - backendService: projects/PROJECT_ID/global/backendServices/blue-service
            weight: 5
    
  7. 点击完成

  8. 点击更新

gcloud

  1. 使用 gcloud compute url-maps export 命令导出现有网址映射:

    gcloud compute url-maps export global-lb-map \
      --destination=global-lb-map-config.yaml \
      --global
    
  2. 将以下内容添加到 global-lb-map-config.yaml 网址映射文件末尾来更新此文件:

    hostRules:
    - hosts:
      - '*'
      pathMatcher: matcher1
    pathMatchers:
    - defaultService: projects/PROJECT_ID/global/backendServices/red-service
      name: matcher1
      routeRules:
      - priority: 2
        matchRules:
          - prefixMatch: /PREFIX
        routeAction:
          weightedBackendServices:
            - backendService: projects/PROJECT_ID/global/backendServices/green-service
              weight: 95
            - backendService: projects/PROJECT_ID/global/backendServices/blue-service
              weight: 5
    
  3. 使用 gcloud compute url-maps import 命令更新网址映射:

    gcloud compute url-maps import global-lb-map \
       --global \
       --source=global-lb-map-config.yaml
    

测试配置

如需测试配置,请先确保对先前设置的负载均衡器的 IP 地址的请求会由默认 red 配置进行处理。

然后检查以确保发送到 FORWARDING_RULE_IP_ADDRESS/prefix 的请求会按预期方式进行拆分。

通过流量控制,您可以根据提供的 Cookie 配置会话亲和性。如需为名为 red-service 的后端服务配置基于 HTTP_COOKIE 的会话亲和性,请按以下说明操作。

  1. 使用 gcloud compute backend_services export 命令获取后端服务配置。

    gcloud compute backend-services export red-service \
        --destination=red-service-config.yaml \
        --global
    
  2. 按如下所示的方式更新 red-service-config.yaml 文件:

    sessionAffinity: 'HTTP_COOKIE'
    localityLbPolicy: 'RING_HASH'
    consistentHash:
     httpCookie:
      name: 'http_cookie'
      path: '/cookie_path'
      ttl:
        seconds: 100
        nanos: 0
     minimumRingSize: 10000
    
  3. red-service-config.yaml 文件中,删除以下行:

    sessionAffinity: NONE
    
  4. 更新后端服务配置文件:

    gcloud compute backend-services import red-service \
        --source=red-service-config.yaml \
        --global
    

问题排查

如果流量未按照您配置的路由规则和流量政策进行路由,您可以根据以下信息来进行问题排查。

如需了解日志记录和监控功能,请参阅外部 HTTP(S) 日志记录和监控

症状:

  • 发往规则中所涉及服务的流量超过相关规则指定的流量。
  • 给定路由规则的 4xx 和 5xx HTTP 响应意外增加。

解决方案:检查路由规则的顺序。路由规则应按其被指定时的顺序进行解释。

网址映射中的路由规则按其被指定时的顺序进行解释。这不同于路径规则的解释方式,后者通过最长前缀匹配进行解释。对于路径规则,全球外部应用负载均衡器仅选择单条路径规则;但是,如果您使用路由规则,则多条规则可能适用。

定义路由规则时,请检查并确保列表顶部的规则不会意外路由原本会通过后续路由规则路由的流量。否则,收到被误发流量的服务可能会拒绝请求,而路由规则中涉及的服务将会收到较少的流量,甚或完全收不到流量。

后续步骤