为内部应用负载均衡器设置流量管理

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

本文档包含以下负载均衡器示例:

  • 区域级外部应用负载均衡器
  • 区域级内部应用负载均衡器
  • 跨区域内部应用负载均衡器

区域级外部应用负载均衡器与区域级内部应用负载均衡器。对于区域级负载均衡器的流量管理配置,区域级网址映射 API区域级后端服务 API 文档提供了完整字段列表,包括关于关系、限制和基数的语义。

这两个负载均衡器之间的唯一区别是负载均衡方案,如下所示:

  • 区域级外部应用负载均衡器使用 EXTERNAL_MANAGED
  • 区域级内部应用负载均衡器使用 INTERNAL_MANAGED

区域级内部应用负载均衡器与跨区域内部应用负载均衡器。对于流量管理配置:

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

准备工作

配置流量管理

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

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

对于区域级内部应用负载均衡器,您还可以使用 Google Cloud 控制台来配置流量管理。

对于区域级内部应用负载均衡器和区域级外部应用负载均衡器,区域级网址映射 API区域级后端服务 API 文档提供了完整字段列表,包括关于关系、限制和基数的语义。

在 Google Cloud 控制台中访问 YAML 示例

如需在 Google Cloud 控制台中访问 YAML 示例,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到负载均衡页面。

    转到“负载均衡”

  2. 点击创建负载均衡器
  3. 完成向导的步骤,以创建区域级内部应用负载均衡器。
  4. 路由规则配置中,选择高级主机、路径和路由规则
  5. 点击添加主机和路径匹配器
  6. 点击代码指南链接。

您将看到路径匹配器 YAML 示例页面。

将流量映射到单项服务

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

    defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
    hostRules:
    - hosts:
      - '*'
      pathMatcher: matcher1
    name: URL_MAP_NAME
    pathMatchers:
    - defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
      name: matcher1
      routeRules:
        - matchRules:
            - prefixMatch: /PREFIX
          priority: 1
          routeAction:
            weightedBackendServices:
              - backendService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
                weight: 100

在两项服务之间拆分流量

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

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

配置网址重定向

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

   defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
   name: URL_MAP_NAME
   hostRules:
   - hosts:
     - "HOST TO REDIRECT FROM" # Use * for all hosts
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/regions/REGION/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/regions/REGION/backendServices/BACKEND_SERVICE_1
   name: regional-lb-map
   region: region/REGION
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: 1
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
               weight: 100
           requestMirrorPolicy:
             backendService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_2
             mirrorPercent: 50.0

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

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

重写请求的网址

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

   defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
   name: regional-lb-map
   region: region/REGION
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/regions/REGION/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/regions/REGION/backendServices/BACKEND_SERVICE_1
   name: regional-lb-map
   region: region/REGION
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
               weight: 100
           retryPolicy:
             retryConditions: 502, 504
             numRetries: 3
             perTryTimeout:
               seconds: 1
               nanos: 500000000

指定路由超时时间

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

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

配置故障注入

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

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

配置 CORS

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

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

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

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

区域级外部应用负载均衡器和内部应用负载均衡器还支持在自定义标头中使用变量。您可以在自定义标头值 (headerValue) 字段中指定一个或多个变量,这些变量之后会转换为相应的具体请求值。如需查看受支持的标头值列表,请参阅在网址映射中创建自定义标头

   defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
   name: regional-lb-map
   region: region/REGION
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: projects/PROJECT_ID/regions/REGION/backendServices/BACKEND_SERVICE_1
               weight: 100
               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: LOAD_BALANCING_SCHEME
    localityLbPolicy: RANDOM
    name: projects/PROJECT_ID/regions/REGION/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
    region: region/REGION

配置熔断

通过熔断功能,您可以设置失败阈值以防止客户端请求导致后端过载。在请求达到您设置的上限后,负载平衡器会停止批准新的连接或发送其他请求,从而为您的后端留出恢复时间。因此,熔断会通过向客户端返回错误而不是让后端过载来防止级联故障。这样一来,您便可处理一些流量,同时为管理过载情况提供时间,例如通过自动扩缩来增加容量以应对流量高峰。

设置每个连接的请求数上限以及到后端服务的连接数。此外,还要限制待处理请求数和重试次数。

    loadBalancingScheme: LOAD_BALANCING_SCHEME # EXTERNAL_MANAGED or INTERNAL_MANAGED
    localityLbPolicy: RANDOM
    affinityCookieTtlSec: 0
    backends:
    - balancingMode: UTILIZATION
      capacityScaler: 1.0
      group: region/REGION/instanceGroups/INSTANCE_GROUP
      maxUtilization: 0.8
    circuitBreakers:
      maxConnections: 1000
      maxPendingRequests: 200
      maxRequests: 1000
      maxRequestsPerConnection: 100
      maxRetries: 3
    connectionDraining:
      drainingTimeoutSec: 0
    healthChecks:
    - region/REGION/healthChecks/HEALTH_CHECK

设置流量拆分:详细步骤

本示例演示了以下步骤:

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

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

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

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

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

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

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

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

  • 使用了路径匹配器。

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

定义服务

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

以下说明假定已创建 HTTP 健康检查 (regional-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-10 \
    --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=LOAD_BALANCING_SCHEME\
    --protocol=HTTP \
    --health-checks=regional-lb-basic-check \
    --health-checks-region="$region" \
    --region="$region"; \
  gcloud compute backend-services add-backend "${name}-service" \
    --balancing-mode='UTILIZATION' \
    --instance-group="${name}-instance-group" \
    --instance-group-zone="$zone" \
    --region="$region")
}

创建服务

调用该函数来创建三项服务,即 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

创建网址映射

gcloud

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

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

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

    gcloud compute url-maps import regional-lb-map \
       --region=us-west1 \
       --source=regional-lb-map-config.yaml
    

测试配置

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

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

创建客户端虚拟机

如需查看相关说明,请参阅在可用区中创建虚拟机实例以测试连接性

将请求发送到 FORWARDING_RULE_IP_ADDRESS

  1. 使用 ssh 连接到客户端。

    gcloud compute ssh global-lb-client-us-west1-a \
       --zone=us-west1-a
    
  2. 运行以下命令:

    for LB_IP in FORWARDING_RULE_IP_ADDRESS; do
       RESULTS=
       for i in {1..1000}; do RESULTS="$RESULTS:`curl ${LB_IP}`"; done >/dev/null 2>&1
       IFS=':'
       echo "***"
       echo "*** Results of load balancing to $LB_IP: "
       echo "***"
       for line in $RESULTS; do echo $line; done | grep -Ev "^$" | sort | uniq -c
       echo
    done
    
检查结果
***
***Results of load balancing to FORWARDING_RULE_IP_ADDRESS:
***
502 red-instance-group-9jvq
498 red-instance-group-sww8

将请求发送到 FORWARDING_RULE_IP_ADDRESS/PREFIX

将请求发送到 FORWARDING_RULE_IP_ADDRESS/PREFIX 并注意流量拆分情况。

for LB_IP in FORWARDING_RULE_IP_ADDRESS; do
    RESULTS=
    for i in {1..1000}; do RESULTS="$RESULTS:`curl ${LB_IP}/PREFIX/index.html`"; done >/dev/null 2>&1
    IFS=':'
    echo "***"
    echo "*** Results of load balancing to $LB_IP/PREFIX: "
    echo "***"
    for line in $RESULTS; do echo $line; done | grep -Ev "^$" | sort | uniq -c
    echo
done
检查结果
***
***Results of load balancing to FORWARDING_RULE_IP_ADDRESS/PREFIX:
***
21 blue-instance-group-8n49
27 blue-instance-group-vlqc
476 green-instance-group-c0wv
476 green-instance-group-rmf4

Canary 设置会成功地将 95% 的 /PREFIX 请求发送到服务 green,并将 5% 的请求发送到服务 blue

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

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

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

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

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

    gcloud compute backend-services import red-service \
        --source=red-service-config.yaml \
        --region=us-west1
    

问题排查

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

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

症状:

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

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

网址映射中的路由规则按其被指定时的顺序进行解释。这不同于路径规则的解释方式,后者通过最长前缀匹配进行解释。若使用路径规则,内部应用负载均衡器只会选择一个路径规则;但是若是使用路由规则,则可能会采用多个路由规则。

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

后续步骤