1. Kubernetes Ingress-Nginx 實現(xiàn)藍綠、灰度發(fā)布

        共 16083字,需瀏覽 33分鐘

         ·

        2021-02-09 21:57

        原文鏈接:https://juejin.cn/post/6844903927318577159

        背景介紹

        某些情況下,我們在使用Kubernetes作為業(yè)務(wù)應(yīng)用的云平臺,想要實現(xiàn)應(yīng)用的藍綠部署用來迭代應(yīng)用版本,用lstio太重太復(fù)雜,而且它本身定位于流控和網(wǎng)格治理;Ingress-Nginx在0.21版本引入了Canary功能,可以為網(wǎng)關(guān)入口配置多個版本的應(yīng)用程序,使用annotation來控制多個后端服務(wù)的流量分配。

        Ingress-Nginx-Annotation Canary 功能介紹

        如果想啟用Canary功能,要先設(shè)置nginx.ingress.kubernetes.io/canary: "true",然后可以啟用以下注釋來配置Canary

        • nginx.ingress.kubernetes.io/canary-weight?請求到Canary ingress中指定的服務(wù)的請求百分比,值為0-100的整數(shù),根據(jù)設(shè)置的值來決定大概有百分之多少的流量會分配Canary Ingress中指定的后端s服務(wù)

        • nginx.ingress.kubernetes.io/canary-by-header?基于request header 的流量切分,適用于灰度發(fā)布或者A/B測試,當(dāng)設(shè)定的hearder值為always是,請求流量會被一直分配到Canary入口,當(dāng)hearder值被設(shè)置為never時,請求流量不會分配到Canary入口,對于其他hearder值,將忽略,并通過優(yōu)先級將請求流量分配到其他規(guī)則

        • nginx.ingress.kubernetes.io/canary-by-header-value?這個配置要和nginx.ingress.kubernetes.io/canary-by-header?一起使用,當(dāng)請求中的hearder key和value 和nginx.ingress.kubernetes.io/canary-by-header?nginx.ingress.kubernetes.io/canary-by-header-value匹配時,請求流量會被分配到Canary Ingress入口,對于其他任何hearder值,將忽略,并通過優(yōu)先級將請求流量分配到其他規(guī)則

        • nginx.ingress.kubernetes.io/canary-by-cookie?這個配置是基于cookie的流量切分,也適用于灰度發(fā)布或者A/B測試,當(dāng)cookie值設(shè)置為always時,請求流量將被路由到Canary Ingress入口,當(dāng)cookie值設(shè)置為never時,請求流量將不會路由到Canary入口,對于其他值,將忽略,并通過優(yōu)先級將請求流量分配到其他規(guī)則

        金絲雀規(guī)則按優(yōu)先順序進行如下排序:canary-by-header - > canary-by-cookie - > canary-weight

        1. 基于權(quán)重的小規(guī)模版本測試

        • v1版本編排文件

        apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx  labels:    app: echoserverv1  name: echoserverv1  namespace: echoserverspec:  rules:  - host: echo.chulinx.com    http:      paths:      - backend:          serviceName: echoserverv1          servicePort: 8080        path: /---kind: ServiceapiVersion: v1metadata:  name:  echoserverv1  namespace: echoserverspec:  selector:    name:  echoserverv1  type:  ClusterIP  ports:  - name:  echoserverv1    port:  8080    targetPort:  8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name:  echoserverv1  namespace: echoserver  labels:    name:  echoserverv1spec:  template:    metadata:      labels:        name:  echoserverv1    spec:      containers:      - image:  mirrorgooglecontainers/echoserver:1.10        name:  echoserverv1         ports:        - containerPort:  8080          name:  echoserverv1
        • 查看v1版本創(chuàng)建的資源

        $ [K8sSj] kubectl get pod,service,ingress -n echoserverNAME                                READY   STATUS    RESTARTS   AGEpod/echoserverv1-657b966cb5-7grqs   1/1     Running   0          24h
        NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/echoserverv1 ClusterIP 10.99.68.72 8080/TCP 24h
        NAME HOSTS ADDRESS PORTS AGEingress.extensions/echoserverv1 echo.chulinx.com 80 24h
        • 訪問v1的服務(wù),可以看到10個請求都是訪問到一個pod上也就是v1版本的服務(wù)
        $ [K8sSj] for i in `seq 10`;do curl -s echo.chulinx.com|grep Hostname;doneHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqs
        • 創(chuàng)建v2版本的服務(wù)

        我們開啟canary功能,將v2版本的權(quán)重設(shè)置為50%,這個百分比并不能精確的將請求平均分配到兩個版本的服務(wù),而是在50%上下浮動

        apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx    nginx.ingress.kubernetes.io/canary: "true"    nginx.ingress.kubernetes.io/canary-weight: "50"  labels:    app: echoserverv2  name: echoserverv2  namespace: echoserverspec:  rules:  - host: echo.chulinx.com    http:      paths:      - backend:          serviceName: echoserverv2          servicePort: 8080        path: /---kind: ServiceapiVersion: v1metadata:  name:  echoserverv2  namespace: echoserverspec:  selector:    name:  echoserverv2  type:  ClusterIP  ports:  - name:  echoserverv2    port:  8080    targetPort:  8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name:  echoserverv2  namespace: echoserver  labels:    name:  echoserverv2spec:  template:    metadata:      labels:        name:  echoserverv2    spec:      containers:      - image:  mirrorgooglecontainers/echoserver:1.10        name:  echoserverv2         ports:        - containerPort:  8080          name:  echoserverv2
        • 創(chuàng)建v2版本的服務(wù)

        我們開啟canary功能,將v2版本的權(quán)重設(shè)置為50%,這個百分比并不能精確的將請求平均分配到兩個版本的服務(wù),而是在50%上下浮動

        apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx    nginx.ingress.kubernetes.io/canary: "true"    nginx.ingress.kubernetes.io/canary-weight: "50"  labels:    app: echoserverv2  name: echoserverv2  namespace: echoserverspec:  rules:  - host: echo.chulinx.com    http:      paths:      - backend:          serviceName: echoserverv2          servicePort: 8080        path: /---kind: ServiceapiVersion: v1metadata:  name:  echoserverv2  namespace: echoserverspec:  selector:    name:  echoserverv2  type:  ClusterIP  ports:  - name:  echoserverv2    port:  8080    targetPort:  8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name:  echoserverv2  namespace: echoserver  labels:    name:  echoserverv2spec:  template:    metadata:      labels:        name:  echoserverv2    spec:      containers:      - image:  mirrorgooglecontainers/echoserver:1.10        name:  echoserverv2         ports:        - containerPort:  8080          name:  echoserverv2
        • 再次查看創(chuàng)建的資源

        $ [K8sSj] kubectl get pod,service,ingress -n echoserverNAME                                READY   STATUS    RESTARTS   AGEpod/echoserverv1-657b966cb5-7grqs   1/1     Running   0          24hpod/echoserverv2-856bb5758-f9tqn    1/1     Running   0          4s
        NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/echoserverv1 ClusterIP 10.99.68.72 8080/TCP 24hservice/echoserverv2 ClusterIP 10.111.103.170 8080/TCP 4s
        NAME HOSTS ADDRESS PORTS AGEingress.extensions/echoserverv1 echo.chulinx.com 80 24hingress.extensions/echoserverv2 echo.chulinx.com 80 4s
        • 訪問測試

        可以看到請求有4個落到v2版本,6個落到v1版本,理論上來說,請求說越多,落到v2版本的請求數(shù)越接近設(shè)置的權(quán)重50%
        $ [K8sSj] for i in `seq 10`;do curl -s echo.chulinx.com|grep Hostname;doneHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqs

        2. 基于header的A/B測試

        • 更改v2版本的編排文件

        增加headernginx.ingress.kubernetes.io/canary-by-header: "v2"

        apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx    nginx.ingress.kubernetes.io/canary: "true"    nginx.ingress.kubernetes.io/canary-weight: "50"    nginx.ingress.kubernetes.io/canary-by-header: "v2"  labels:    app: echoserverv2  name: echoserverv2  namespace: echoserverspec:  rules:  - host: echo.chulinx.com    http:      paths:      - backend:          serviceName: echoserverv2          servicePort: 8080        path: /---kind: ServiceapiVersion: v1metadata:  name:  echoserverv2  namespace: echoserverspec:  selector:    name:  echoserverv2  type:  ClusterIP  ports:  - name:  echoserverv2    port:  8080    targetPort:  8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name:  echoserverv2  namespace: echoserver  labels:    name:  echoserverv2spec:  template:    metadata:      labels:        name:  echoserverv2    spec:      containers:      - image:  mirrorgooglecontainers/echoserver:1.10        name:  echoserverv2         ports:        - containerPort:  8080          name:  echoserverv2
        • 更新訪問測試

        測試了header 為v2:always?v2:never?v2:true這三個hearder值,可以看到當(dāng)hearder為v2:always時,流量會全部流入v2,當(dāng)v2:never時,流量會全部流入v1,當(dāng)v2:true時,也就是非always/never,流量會按照配置的權(quán)重流入對應(yīng)版本的服務(wù)

        $ [K8sSj] kubectl apply -f appv2.ymlingress.extensions/echoserverv2 configuredservice/echoserverv2 unchangeddeployment.extensions/echoserverv2 unchanged
        $ [K8sSj] for i in `seq 10`;do curl -s -H "v2:always" echo.chulinx.com|grep Hostname;doneHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqn
        $ [K8sSj] for i in `seq 10`;do curl -s -H "v2:never" echo.chulinx.com|grep Hostname;doneHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqs
        $ [K8sSj] for i in `seq 10`;do curl -s -H "v2:true" echo.chulinx.com|grep Hostname;doneHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqn
        • 自定義header-value

        apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    kubernetes.io/ingress.class: nginx    nginx.ingress.kubernetes.io/canary: "true"    nginx.ingress.kubernetes.io/canary-weight: "50"    nginx.ingress.kubernetes.io/canary-by-header: "v2"    nginx.ingress.kubernetes.io/canary-by-header-value: "true"  labels:    app: echoserverv2  name: echoserverv2  namespace: echoserverspec:  rules:  - host: echo.chulinx.com    http:      paths:      - backend:          serviceName: echoserverv2          servicePort: 8080        path: /---kind: ServiceapiVersion: v1metadata:  name:  echoserverv2  namespace: echoserverspec:  selector:    name:  echoserverv2  type:  ClusterIP  ports:  - name:  echoserverv2    port:  8080    targetPort:  8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name:  echoserverv2  namespace: echoserver  labels:    name:  echoserverv2spec:  template:    metadata:      labels:        name:  echoserverv2    spec:      containers:      - image:  mirrorgooglecontainers/echoserver:1.10        name:  echoserverv2         ports:        - containerPort:  8080          name:  echoserverv2
        • 更新測試

        可以看到只有header為v2:never時,請求流量才會流入v2版本,其他值流量都會按照權(quán)重設(shè)置流入不通版本的服務(wù)
        $ [K8sSj] kubectl apply -f appv2.ymlingress.extensions/echoserverv2 configuredservice/echoserverv2 unchangeddeployment.extensions/echoserverv2 unchanged
        $ [K8sSj] for i in `seq 10`;do curl -s -H "v2:true" echo.chulinx.com|grep Hostname;doneHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqn
        $ [K8sSj] for i in `seq 10`;do curl -s -H "v2:always" echo.chulinx.com|grep Hostname;doneHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqn
        $ [K8sSj] for i in `seq 10`;do curl -s -H "v2:never" echo.chulinx.com|grep Hostname;doneHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqs
        • 訪問測試

        可以看和header的訪問效果是一樣的,只不過cookie不能自定義value

        $ [K8sSj] kubectl apply -f appv2.ymlingress.extensions/echoserverv2 configuredservice/echoserverv2 unchangeddeployment.extensions/echoserverv2 unchanged
        $ [K8sSj] for i in `seq 10`;do curl -s --cookie "user_from_shanghai" echo.chulinx.com|grep Hostname;doneHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqn
        # zlx @ zlxdeMacBook-Pro in ~/Desktop/unicom/k8syml/nginx-ingress-canary-deployment [16:01:52]$ [K8sSj] for i in `seq 10`;do curl -s --cookie "user_from_shanghai:always" echo.chulinx.com|grep Hostname;doneHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv1-657b966cb5-7grqsHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqn
        # zlx @ zlxdeMacBook-Pro in ~/Desktop/unicom/k8syml/nginx-ingress-canary-deployment [16:02:25]$ [K8sSj] for i in `seq 10`;do curl -s --cookie "user_from_shanghai=always" echo.chulinx.com|grep Hostname;doneHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqnHostname: echoserverv2-856bb5758-f9tqn

        總結(jié)

        灰度發(fā)布可以保證整體系統(tǒng)的穩(wěn)定,在初始灰度的時候就可以對新版本進行測試、發(fā)現(xiàn)和調(diào)整問題,以保證其影響度,以上內(nèi)容通過實例詳細介紹了Ingress-Nginx的實戰(zhàn)Canary Annotation,可以借助Ingress-Nginx輕松實現(xiàn)藍綠發(fā)布和金絲雀發(fā)布

        其他

        關(guān)于藍綠發(fā)布、金絲雀發(fā)布、和A/B測試

        • 藍綠發(fā)布

        藍綠部署中,一共有兩套系統(tǒng):一套是正在提供服務(wù)系統(tǒng),標(biāo)記為“綠色”;另一套是準(zhǔn)備發(fā)布的系統(tǒng),標(biāo)記為“藍色”。兩套系統(tǒng)都是功能完善的,并且正在運行的系統(tǒng),只是系統(tǒng)版本和對外服務(wù)情況不同。
        最初,沒有任何系統(tǒng),沒有藍綠之分。
        然后,第一套系統(tǒng)開發(fā)完成,直接上線,這個過程只有一個系統(tǒng),也沒有藍綠之分。
        后來,開發(fā)了新版本,要用新版本替換線上的舊版本,在線上的系統(tǒng)之外,搭建了一個使用新版本代碼的全新系統(tǒng)。這時候,一共有兩套系統(tǒng)在運行,正在對外提供服務(wù)的老系統(tǒng)是綠色系統(tǒng),新部署的系統(tǒng)是藍色系統(tǒng)。
        藍色系統(tǒng)不對外提供服務(wù),用來做啥?
        用來做發(fā)布前測試,測試過程中發(fā)現(xiàn)任何問題,可以直接在藍色系統(tǒng)上修改,不干擾用戶正在使用的系統(tǒng)。(注意,兩套系統(tǒng)沒有耦合的時候才能百分百保證不干擾)
        藍色系統(tǒng)經(jīng)過反復(fù)的測試、修改、驗證,確定達到上線標(biāo)準(zhǔn)之后,直接將用戶切換到藍色系統(tǒng):
        切換后的一段時間內(nèi),依舊是藍綠兩套系統(tǒng)并存,但是用戶訪問的已經(jīng)是藍色系統(tǒng)。這段時間內(nèi)觀察藍色系統(tǒng)(新系統(tǒng))工作狀態(tài),如果出現(xiàn)問題,直接切換回綠色系統(tǒng)。
        當(dāng)確信對外提供服務(wù)的藍色系統(tǒng)工作正常,不對外提供服務(wù)的綠色系統(tǒng)已經(jīng)不再需要的時候,藍色系統(tǒng)正式成為對外提供服務(wù)系統(tǒng),成為新的綠色系統(tǒng)。原先的綠色系統(tǒng)可以銷毀,將資源釋放出來,用于部署下一個藍色系統(tǒng)。
        藍綠部署只是上線策略中的一種,它不是可以應(yīng)對所有情況的萬能方案。藍綠部署能夠簡單快捷實施的前提假設(shè)是目標(biāo)系統(tǒng)是非常內(nèi)聚的,如果目標(biāo)系統(tǒng)相當(dāng)復(fù)雜,那么如何切換、兩套系統(tǒng)的數(shù)據(jù)是否需要以及如何同步等,都需要仔細考慮。
        • 金絲雀發(fā)布

        金絲雀發(fā)布(Canary)也是一種發(fā)布策略,和國內(nèi)常說的灰度發(fā)布是同一類策略。藍綠部署是準(zhǔn)備兩套系統(tǒng),在兩套系統(tǒng)之間進行切換,金絲雀策略是只有一套系統(tǒng),逐漸替換這套系統(tǒng)

        譬如說,目標(biāo)系統(tǒng)是一組無狀態(tài)的Web服務(wù)器,但是數(shù)量非常多,假設(shè)有一萬臺。
        這時候,藍綠部署就不能用了,因為你不可能申請一萬臺服務(wù)器專門用來部署藍色系統(tǒng)(在藍綠部署的定義中,藍色的系統(tǒng)要能夠承接所有訪問)。

        可以想到的一個方法是:

        只準(zhǔn)備幾臺服務(wù)器,在上面部署新版本的系統(tǒng)并測試驗證。測試通過之后,擔(dān)心出現(xiàn)意外,還不敢立即更新所有的服務(wù)器。先將線上的一萬臺服務(wù)器中的10臺更新為最新的系統(tǒng),然后觀察驗證。確認沒有異常之后,再將剩余的所有服務(wù)器更新。
        這個方法就是金絲雀發(fā)布。

        實際操作中還可以做更多控制,譬如說,給最初更新的10臺服務(wù)器設(shè)置較低的權(quán)重、控制發(fā)送給這10臺服務(wù)器的請求數(shù),然后逐漸提高權(quán)重、增加請求數(shù)。

        這個控制叫做“流量切分”,既可以用于金絲雀發(fā)布,也可以用于后面的A/B測試。
        藍綠部署和金絲雀發(fā)布是兩種發(fā)布策略,都不是萬能的。有時候兩者都可以使用,有時候只能用其中一種。

        • A/B測試

        首先需要明確的是,A/B測試和藍綠部署以及金絲雀,完全是兩回事。

        藍綠部署和金絲雀是發(fā)布策略,目標(biāo)是確保新上線的系統(tǒng)穩(wěn)定,關(guān)注的是新系統(tǒng)的BUG、隱患。

        A/B測試是效果測試,同一時間有多個版本的服務(wù)對外服務(wù),這些服務(wù)都是經(jīng)過足夠測試,達到了上線標(biāo)準(zhǔn)的服務(wù),有差異但是沒有新舊之分(它們上線時可能采用了藍綠部署的方式)。

        A/B測試關(guān)注的是不同版本的服務(wù)的實際效果,譬如說轉(zhuǎn)化率、訂單情況等。

        A/B測試時,線上同時運行多個版本的服務(wù),這些服務(wù)通常會有一些體驗上的差異,譬如說頁面樣式、顏色、操作流程不同。相關(guān)人員通過分析各個版本服務(wù)的實際效果,選出效果最好的版本。

        在A/B測試中,需要能夠控制流量的分配,譬如說,為A版本分配10%的流量,為B版本分配10%的流量,為C版本分配80%的流量。

        - END -

        公眾號后臺回復(fù)「加群」加入一線高級工程師技術(shù)交流群,一起交流進步。

        ?推薦閱讀?

        31天拿下Kubernetes CKA認證!
        2021最新 Kubernetes 運維架構(gòu)師實戰(zhàn)指南?
        一文搞懂藍綠發(fā)布、灰度發(fā)布和滾動發(fā)布
        Kubernetes 集群網(wǎng)絡(luò)從懵圈到熟悉
        一篇文章搞懂日志采集利器 Filebeat
        Prometheus 監(jiān)控服務(wù)端口、網(wǎng)站狀態(tài)等(黑盒監(jiān)測)
        Kubernetes 學(xué)習(xí)筆記總結(jié),超詳細!
        Kubernetes生產(chǎn)環(huán)境最佳實踐



        點亮,服務(wù)器三年不宕機

        瀏覽 58
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 日韩无码性生活视频 | 99久久人妻精品免费二区 | 五月婷婷丁香社区 | 久热精品99 | 亚洲乱伦视频网 |