為全域外部應用程式負載平衡器設定流量管理

本文將舉例說明如何運用流量管理功能處理特定用途。還能用於許多其他用途。

這份文件包含全域外部應用程式負載平衡器的範例。全域外部應用程式負載平衡器使用 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 回應標頭,以取代重新導向動作中所指定的主機和路徑。

如要為後端 bucket 建立重新導向,請使用 projects/PROJECT_ID/global/backendBuckets/BACKEND_BUCKET defaultService 欄位。

   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 政策

在這個設定中,CORS 政策是在路徑比對器 (pathMatchers[].defaultRouteAction.corsPolicy) 的 defaultRouteAction 中定義。這表示無論特定路徑或路由為何,透過預設路徑比對器路由的所有要求都會套用這項政策。

如果您希望路徑比對工具管理的所有路徑都採用一致的單一 CORS 政策,就適合使用這個方法。

defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
name: global-lb-map
hostRules:
- hosts:
  - '*'
  pathMatcher: path-matcher-1
pathMatchers:
- defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_1
  name: path-matcher-1
- defaultRouteAction:
    corsPolicy:
      allowCredentials: true
      allowOrigins: [ "http://example.com" ]
      allowMethods: [ "GET", "POST" ]
      allowHeaders: [ "Authorization", "Content-Type" ]

運作方式

  • 負載平衡器會針對路徑比對器處理的所有要求,強制執行 CORS 政策。
  • 系統只允許來自主機 example.com 的要求,且這些要求必須使用 GET 或 POST 方法,並包含允許的標頭 (Authorization、Content-Type)。
  • 允許在跨來源要求中使用憑證 (例如 Cookie 或授權標頭)。
  • 後端服務只會收到符合這項 CORS 政策的要求。

在路由規則層級套用 CORS 政策

在這個設定中,CORS 政策是在特定路徑規則 (pathMatchers[].routeRules[].routeAction.corsPolicy) 的 routeAction 中定義。這樣一來,您就能對不同路徑或路徑前置碼套用不同的 CORS 政策。

如果您需要精細控管,例如對不同的 API 端點或路徑套用不同的 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://example.com" ]
               allowMethods: [ "GET", "POST" ]
               allowHeaders: [ "Authorization", "Content-Type" ]
               maxAge: 1200
               allowCredentials: true

運作方式

  • 只有符合指定路徑前置字元 (例如 /PREFIX) 的要求,才會強制執行 CORS 政策。
  • 只有來自主機 example.com 的要求 (使用 GET 或 POST 方法),以及具有允許標頭的要求,才能使用這條路徑。
  • maxAge 欄位會指定瀏覽器可以快取預檢要求結果的時間長度 (以秒為單位)。
  • 跨原始來源要求中允許使用憑證。
  • 其他路徑可能會有不同的 CORS 政策,或完全沒有政策。

您也可以在網址對應的下列層級定義 CORS 政策:

  • defaultRouteAction.corsPolicy
  • pathMatchers[].pathRules[].routeAction.corsPolicy

新增及移除要求和回應標頭

在將要求傳送至後端服務之前,新增及移除要求標頭。從後端服務收到回應後,這項設定也可以新增或刪除回應標頭。

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 中健康狀態不良的後端 VM 或端點的條件,也會定義條件,決定後端或端點何時會被視為健康狀態良好到足以再次接收流量。請務必替換預留位置。

    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 指令,顯示流量拆分百分比大致與設定相符。

此處的操作說明假設情況如下:

  • 已建立目標 Proxy 和轉送規則,以及名為 global-lb-map 的網址對應。

  • 網址對應會將所有流量傳送到名為 red-service 的預設後端服務。

  • 您設定的替代路徑會分別將 5% 和 95% 的流量傳送至 blue-servicegreen-service

  • 使用路徑比對器。

  • 您正在使用 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)
}

建立服務

呼叫函式來提供 redgreenblue 三項服務。red 服務是 / 要求的預設服務。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 控制台的「Load balancing」(負載平衡) 頁面。
    前往「Load balancing」(負載平衡)
  2. 按一下「global-lb-map」連結。
  3. 按一下「編輯」圖示

設定新的轉送規則

  1. 在「Routing rules」(轉送規則) 下方,選取「Advanced host, path and route rule」(進階型主機、路徑與轉送規則)
  2. 在「新增主機和路徑比對器」下方,將「服務」設為 red-service,建立預設動作。
  3. 按一下 [完成]
  4. 按一下「新增主機和路徑比對器」
  5. 在「Hosts」欄位中,輸入負載平衡器轉送規則的 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. 按一下「Update」

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 回應非預期增加。

解決方案:檢查轉送規則的順序。轉送規則會按照其指定順序進行解譯。

網址對應中的轉送規則會按照其指定順序進行解譯。這與根據最長前置字元相符項目解譯路徑規則的方式不同。如為路徑規則,全域外部應用程式負載平衡器只會選取一個路徑規則。但是當您使用轉送規則時,可能會有多個規則均適用。

定義轉送規則時,請確認清單頂端的規則不會意外轉送原先會由後續轉送規則所轉送的流量。接收錯誤導向流量的服務可能會拒絕要求,且轉送規則中的服務所收到的流量會減少或完全沒有流量。

後續步驟