文章段落
Google 的 Cloud Load Balancing 能在龐大流量湧入時分散負載,避免單一伺服器負載過高,進而達到資源使用最佳化。除此之外,它還能進行流量管理,實現 A/B 測試和金絲雀部署等功能!這次分享 3 種以 Cloud Load Balancing 管理流量的方法教學,快來一起實作看看吧。
在《用 GCP HTTP(S) Load Balancing 實現 HTTP Redirect HTTPS》一文中我們了解 Cloud Load Balancing 可將 HTTP 流量轉至 HTTPS,但它能否像 Cloud Run、Google Kubernetes Engine Anthos service mesh、App Engine 和 Kubernetes Istio 或 Gateway API 等服務,實現如 A/B 測試、金絲雀部署和 Shadow 測試等流量管理功能,減少架構或開發負擔呢?其實只要以 Cloud Load Balancing 的 Advanced host and path rule 撰寫 yaml,指定流量前往哪些 backend service 或 backend bucket 就可以囉!以下提供「權重分配」、「以 HTTP Header 指定」,和「訪問 backend bucket」三種方式的實作教學。
Cloud Load Balancing 流量管理教學一:權重分配
實作架構
權重分配需求:
1. 所有利用 IP 來的請求一律不提供服務
2. 只替從 Domain 前來且 Path 為 /api/v1 的請求提供服務
3. 以 8:2 的權重比例分配前往 v1 和 v2 的流量
根據需求我們設計的架構圖如下。此次教學聚焦於流量管理方法,因此以 Compute Engine(GCE)建立 Instance group、backend service 和 Load balancer 的方法這邊就不贅述,詳情可參考《【GCP 教學】負載平衡 Load Balancer 和 Instance Group》一文。

根據上述需求,我們除了要讓流量按權重比例分配,還要拒絕替以 IP 來的請求提供服務。為此我們要增設一個 black hole,也就是無 GCE 的 backend service,下面一起來了解設置方法。
前置作業:建置無 GCE 的 backend service
首先前往 Google Cloud Console,在左上角的 menu 找到位在 Network services 內的 Load Balancing。接著點選 BACKENDS 內的 CREATE BACKEND SERVICE。
截圖自:Google Cloud Console
©2023 Google
再來我們在 backend service 選擇要使用的 Load Balancer 類型,點擊 CREATE 開始建立。進入後找到 New backend 的方塊並點擊右上方的垃圾桶 icon 將其刪除。最後只要完成必填設定就能成功建立具 black hole 功能的 backend service。
截圖自:Google Cloud Console
©2023 Google
撰寫權重分配的 URL Map
完成 Load Balancer 跟 backend service 後就能設計流量管理了,但這部分目前 Google Cloud Console 還不支援 UI 操作,只能透過 yaml 設計,所以有操作需求的人可至 CloudAce 的 GitHub 取得 yaml 範例檔案。

上圖 yaml 檔內的紅色區塊是基本內容,包含 Load Balancer 的名字、能辨識的 host 與對應的 path。藍色區塊是 hosts,而綠色跟棕色是各別的 path 規則。各顏色區塊的詳細內容說明如下。
紅色區塊
- name:string (字串)格式,需填入此 Load Balancer 的名字。
- defaultService:當 string 沒滿足任何規則時,就利用 black hole 這個 backend service。
- hostRules:紀錄所有的 host,包含域名跟 IP,詳情見藍色區塊的說明。
- pathMatchers:紀錄所有的 path 規則,詳情見綠色跟棕色區塊的說明。
藍色區塊(hostRules 部分)
hostRules 是 array(陣列)格式,可放入多組 host rules,下圖的 yaml 是放兩組 hosts,分別為一筆域名(xxx.endpoints.xxxxx.cloud.goog)跟一筆 IP(34.xx.xx.xx)。
- hosts:array 格式,可放入多筆 hosts。下圖示範填入一筆域名,但實際可填入筆數不限。
- pathMatcher:string 格式,需填入對應的 path match 規則(綠色跟棕色部分),只能一對一,不能一對多。

綠色跟棕色區塊(pathMatchers 部分)
pathMatchers 是 array 格式,可放入多組以 path match 為依據的規則。此次教學是設定兩組規則給 hostRules.pathMatcher 對應使用。
- defaultService:string 格式,path 層級下預設的 backend service。當任何 path 條件都不滿足時就採用該預設 backend service,此處設定為 black hole。
- name:string 格式,為此 pathMatcher 的名字,主要提供給 hostRules.pathMatcher 索引。此次教學使用「normal-svc」與「blackhole-svc」。
- routeRule:array 格式,可放入多組以 URL path 為依據的 rules。圖 1 是各放一組,但實際可填組數不限。
- matchRules:array 格式,可放入多組檢查 path 的規則,條件是「或」。如:prefixMatch(前綴相同)、fullPathMatch(完全相同)、regexMatch(正規表示式,僅限 internal Load Balancer 使用)。以下圖 yaml 為例是前綴包含「/api/v1/」的路徑(如: /api/v1/products、/api/v1/products/uuid)皆會前往指定的 backend service。
- priority:須為整數,代表優先順序。愈小愈優先,當 matchRules 相同時,可藉由 priority 決定優先順序。但要注意,priority 須由小到大依序填入。
- routeAction:object 格式,用來輸入要前往的 backend service 及對應的權重(0 ~ 100),讓流量按權重分配。如圖 2 寫法表示 80% 流量前往 version-1;20% 流量前往 version-2。
- service:string 格式,用來輸入 backend service 的名字,讓流量前往指定的 service。需特別注意,routeAction 跟 service 只能擇一使用。
部署與測試
完成 yaml 檔後,就可使用下方的 gcloud 指令部署到 Load Balancer。部署好後我們使用 curl 簡單測試,可發現 v2 在 20 次中出現 3 次,比例為 15%。未達到 20% 是因為請求量偏低,請求量愈大,v1 和 v2 接收的流量比例就會愈接近我們設定的數值。
gcloud compute url-maps import <LB_NAME> \
--global \
--source=<FILE_PARH> \
--project=<PROJECT_ID>

Cloud Load Balancing 流量管理教學二:以 HTTP Header 指定
實作架構
這次我們接續方法一的權重分配情境,再增加 header 的需求(第 4 點)。
以 HTTP Header 指定流量分配的需求:
1. 所有利用 IP 來的請求一律不提供服務
2. 只替從 Domain 前來且 Path 為 /api/v1 的請求提供服務
3. 以 8:2 的權重比例分配前往 v1 和 v2 的流量
4. header(target=v2)可直接前往 v2

撰寫以 HTTP Header 指定流量分配的 URL Map
因為流量分配需求和方法一大致相同,所以只要在方法一的 yaml 內新一組 matchRules(下圖紅字區塊)即可,設定細節如下。
- headerMatches:array 格式,可放入多組要判斷的 header。下圖示範檢查一組 header 為 key=target、value=v2。
- headerName:string 格式,需填入 header key name。
- exactMatch:string 格式,進行完整比對。下圖示範檢查 header.target 的值為 「v2」。
- prefixMatch:string 格式,用以比對前綴。
- presentMatch:須為布林值,判斷是否存在,只要 header 有存在這個 key 即可。
- regexMatch:regex string 格式,以正規表示式比對,僅限 internal Load Balancer 使用。
- suffixMatch:string 格式,用以比對後綴。
- rangeMatch:string 格式,用以比對範圍,需注意下述條件只能擇一使用。
- rangeStart:須為整數,起始值(包含)
- rangeEnd:須為整數,終止值(不包含)
- invertMatch:須為布林值並與上述條件並存,替上述條件執行反向(非,不)結果。若設定為 true,則表示 header 沒有 target=v2 才可以進來。

部署與測試
寫好 yaml 後一樣利用下方 gcloud 指令部署將其部署到 URL map,並使用 curl 簡單測試。可發現我們讓 header(target=v2)的請求可直接前往指定的 backend service(v2)。
gcloud compute url-maps import <LB_NAME> \
--global \
--source=<FILE_PARH> \
--project=<PROJECT_ID>

Cloud Load Balancing 流量管理教學三:訪問 backend bucket
實作架構
最後一種方法我們繼續接著前段 header 指定的架構,再增加 backend bucket,讓請求訪問 bucket 底下的 static(靜態檔案)。
以 HTTP Header 指定流量分配的需求:
1. 所有利用 IP 來的請求一律不提供服務
2. 只替從 Domain 前來且 Path 為 /api/v1 的請求提供服務
3. 以 8:2 的權重比例分配前往 v1 和 v2 的流量
4. header(target=v2)可直接前往 v2
5. Path /static/ 下的請求都前往 Cloud Storage bucket
撰寫指定訪問 backend bucket 的 URL Map
延續方法二的 yaml,我們再增加一組 matchRules(下圖紫字區塊)。backend bucket 與 backend service 一樣使用 service 這個 yaml object,其餘設定則沿用上面介紹的做法。

部署與測試
最後再次將寫好的 yaml 以 gcloud 指令部署到 URL map,用瀏覽器前往確認可成功訪問 static。
gcloud compute url-maps import <LB_NAME> \
--global \
--source=<FILE_PARH> \
--project=<PROJECT_ID>
結論
以上就是利用 Cloud Load Balancing 實現細緻流量管理的三種方法教學。以權重分配來說,可以利用低權重的分配,實現金絲雀部署或 A/B test。而以 header 切換流量的方法,則能利用 header 區分來訪的使用者,提供不同的 backend service。但除此之外,URL Map 流量管理可以做到更多的事情,如:請求重試(request retry)、跨來源資源存取(Cross-origin resource sharing,CORS)的 header 檢查,和 URL redirect、rewrite 等,詳細可以參考《Set up traffic management for global external Application Load Balancers》這份官方說明。
整體而言,可控的流量能為網站擁有者帶來動態調整服務的彈性,不用擔心每次上版都影響到全部的使用者。若有進一步的流量管理需求或 Cloud Load Balancing 操作疑問,歡迎聯絡 Cloud Ace 獲得更進一步的資訊。
▋延伸閱讀:
・什麼是負載平衡?原理、6大 GCP Load Balancer 完整介紹
・GCP HTTP(S) Load Balancer 負載平衡依網址分流教學
・【GCP 教學】負載平衡 Load Balancer 和 Instance Group
・Cloud Run 是什麼?6大特色介紹與實作教學
