微服務1:微服務及其演進史
微服務2:微服務全景架構
微服務3:微服務拆分策略
微服務4:服務註冊與發現
微服務5:服務註冊與發現(實踐篇)
微服務6:通訊之閘道器
微服務7:通訊之RPC
微服務8:通訊之RPC實踐篇(附原始碼)
微服務9:服務治理來保證高可用
微服務10:系統服務熔斷、限流
微服務11:熔斷、降級的Hystrix實現(附原始碼)
微服務12:流量策略
微服務提供了一些技術來實現對微服務的流量的管理,其中最典型的就是對流量進行拆分和轉發。
具體體現在金絲雀釋出(灰度釋出)、ABTesting 以及流量染色 等策略方案上。
雲原生基礎場景下,如果想要實現流控和排程,需要具備以下幾個條件:
所以,流控排程的本質上是通過在流量中攜帶一些特徵(如流量的請求的Header、Cookies、queryParams等),而Mesh會根據這些請求的特徵進行路由匹配,轉發到對應的帶有某些特徵的服務範例上。
未匹配成功的流量則走到預設版本或者給定的具體版本中,從而實現多個版本和跟預設版本的業務隔離的目標。這種模式下,實現 灰度釋出、ABTesting 以及流量染色 都是很方便的。
這邊以Istio 實現的 Service-Mesh為案例
基於上述的策略模型,如果你想設定如下:請求的header 帶有 username = brand 或者 departname = hr 的時候,將流量轉發到服務的v1版本,否著轉發到default版本。
則策略程式碼如下:
# 說明:VirtualService 流量染色,根據不同的條件將流量發往不同特徵的版本中,假設這邊有default、v1、v2 版本
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-service1-vs
spec:
hosts:
- test-service1 # 治理髮往test-service1服務的流量
exportTo:
- "."
http: # 加各種路由條件,比如匹配人員、部門進行路由
- match # 使用者匹配 brand,部門匹配 hr 部門時
- headers:
username:
exact: brand
- headers:
departname:
exact: hr
route:
destination:
# todo 匹配條件的流量路由到對應的服務上......
- route:
- destination:
# todo 不匹配條件的流量路由到對應的服務上......
雲原生基礎平臺上的服務遵循如下層級結構,namespace對標應用,svc對標服務。
假設你給你的服務設定了多個版本,比如你釋出了default(預設版本)、v1版本。
檢查kubernetes的資訊會發現,service保持不變,這個命名為testsvc-admin-default的服務下,對應兩個deployment,兩個pod。
root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
testsvc-admin-429mvh 1/1 1 1 18m
testsvc-admin-default 1/1 1 1 142m
root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
testsvc-admin-default ClusterIP 172.100.110.220 <none> 80/TCP 142m
root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get pods
NAME READY STATUS RESTARTS AGE
testsvc-admin-429mvh-5b567969b4-nq4zp 2/2 Running 0 17m
testsvc-admin-default-85467f8f79-xzfgz 2/2 Running 0 23m
看看兩個deployment的資訊對比,labels中的app屬性一致,version屬性不一致。所以,服務按照同一個app定址,不同的version進行流量shift的方式進行。
root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get deployment testsvc-admin-default -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "2"
creationTimestamp: "2022-01-14T06:40:22Z"
generation: 2
labels:
app: testsvc-admin-default
appName: testsvc-admin
appType: java
projectName: testsvc-debug
version: default
workspaceName: SPACE_BASIC_SERVE
name: testsvc-admin-default
namespace: testsvc-debug
resourceVersion: "335716111"
uid: 7531a9b3-53eb-475d-ae0b-75df957badb9
root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get deployment testsvc-admin-429mvh -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2022-01-14T08:45:03Z"
generation: 1
labels:
app: testsvc-admin-default
appName: testsvc-admin
appType: java
projectName: testsvc-debug
version: 429mvh
workspaceName: SPACE_BASIC_SERVE
name: testsvc-admin-429mvh
namespace: testsvc-debug
resourceVersion: "335719639"
uid: 85c0e1f2-b56d-4afc-8c51-ccb887e420b6
現在,envoy的流轉規則有了,服務的特徵也有了,完整策略匹配程式碼如下:
# 說明:VirtualService 流量染色,根據不同的條件將流量發往不同特徵的版本中,假設這邊有default、v1、v2 版本
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-svc-vs
spec:
hosts:
- test-svc # 治理髮往test-svc服務的流量
exportTo:
- "."
http: # 加各種路由條件,比如匹配人員、部門進行路由
- match # 使用者匹配 brand,部門匹配 hr 人事部時
- headers:
username:
exact: brand
- headers:
departname:
exact: hr
route:
destination:
host: test-svc
subset: v1 # 匹配條件的流量路由到對應的服務的v1版本上
- route:
- destination:
host: test-svc # 剩餘的流量走到default版本上
subset: default
規則下發之後,envoy儲存在本地,當流量出去的時候,outbound 那邊會做一個判斷。
如果是header中帶上 username = brand 或者 departname = hr ,流量轉發到帶有v1 標籤的pod中,
否則流量轉發到帶有default標籤的pod中。
豐富的流量管理策略為我們系統的穩定性,以及流量的多樣化(金絲雀釋出、ABTesting、分級擴散流量、流量染色)使用提供了保證。