Kubernetes Ingress-Nginx 實(shí)現(xiàn)藍(lán)綠、灰度發(fā)布
背景介紹
某些情況下,我們?cè)谑褂肒ubernetes作為業(yè)務(wù)應(yīng)用的云平臺(tái),想要實(shí)現(xiàn)應(yīng)用的藍(lán)綠部署用來(lái)迭代應(yīng)用版本,用lstio太重太復(fù)雜,而且它本身定位于流控和網(wǎng)格治理;Ingress-Nginx在0.21版本引入了Canary功能,可以為網(wǎng)關(guān)入口配置多個(gè)版本的應(yīng)用程序,使用annotation來(lái)控制多個(gè)后端服務(wù)的流量分配。
Ingress-Nginx-Annotation Canary 功能介紹
如果想啟用Canary功能,要先設(shè)置
nginx.ingress.kubernetes.io/canary: "true",然后可以啟用以下注釋來(lái)配置Canary
nginx.ingress.kubernetes.io/canary-weight?請(qǐng)求到Canary ingress中指定的服務(wù)的請(qǐng)求百分比,值為0-100的整數(shù),根據(jù)設(shè)置的值來(lái)決定大概有百分之多少的流量會(huì)分配Canary Ingress中指定的后端s服務(wù)nginx.ingress.kubernetes.io/canary-by-header?基于request header 的流量切分,適用于灰度發(fā)布或者A/B測(cè)試,當(dāng)設(shè)定的hearder值為always是,請(qǐng)求流量會(huì)被一直分配到Canary入口,當(dāng)hearder值被設(shè)置為never時(shí),請(qǐng)求流量不會(huì)分配到Canary入口,對(duì)于其他hearder值,將忽略,并通過(guò)優(yōu)先級(jí)將請(qǐng)求流量分配到其他規(guī)則nginx.ingress.kubernetes.io/canary-by-header-value?這個(gè)配置要和nginx.ingress.kubernetes.io/canary-by-header?一起使用,當(dāng)請(qǐng)求中的hearder key和value 和nginx.ingress.kubernetes.io/canary-by-header?nginx.ingress.kubernetes.io/canary-by-header-value匹配時(shí),請(qǐng)求流量會(huì)被分配到Canary Ingress入口,對(duì)于其他任何hearder值,將忽略,并通過(guò)優(yōu)先級(jí)將請(qǐng)求流量分配到其他規(guī)則nginx.ingress.kubernetes.io/canary-by-cookie?這個(gè)配置是基于cookie的流量切分,也適用于灰度發(fā)布或者A/B測(cè)試,當(dāng)cookie值設(shè)置為always時(shí),請(qǐng)求流量將被路由到Canary Ingress入口,當(dāng)cookie值設(shè)置為never時(shí),請(qǐng)求流量將不會(huì)路由到Canary入口,對(duì)于其他值,將忽略,并通過(guò)優(yōu)先級(jí)將請(qǐng)求流量分配到其他規(guī)則
金絲雀規(guī)則按優(yōu)先順序進(jìn)行如下排序:canary-by-header - > canary-by-cookie - > canary-weight
1. 基于權(quán)重的小規(guī)模版本測(cè)試
v1版本編排文件
apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:: nginxlabels:app: echoserverv1name: echoserverv1namespace: echoserverspec:rules:host: echo.chulinx.comhttp:paths:backend:serviceName: echoserverv1servicePort: 8080path: /---kind: ServiceapiVersion: v1metadata:name: echoserverv1namespace: echoserverspec:selector:name: echoserverv1type: ClusterIPports:name: echoserverv1port: 8080targetPort: 8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: echoserverv1namespace: echoserverlabels:name: echoserverv1spec:template:metadata:labels:name: echoserverv1spec:containers:image: mirrorgooglecontainers/echoserver:1.10name: echoserverv1ports:containerPort: 8080name: echoserverv1
查看v1版本創(chuàng)建的資源
[K8sSj] kubectl get pod,service,ingress -n echoserverNAME READY STATUS RESTARTS AGE1/1 Running 0 24hNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEClusterIP 10.99.68.728080/TCP 24h NAME HOSTS ADDRESS PORTS AGEecho.chulinx.com 80 24h
訪問(wèn)v1的服務(wù),可以看到10個(gè)請(qǐng)求都是訪問(wèn)到一個(gè)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ù)
我們開(kāi)啟canary功能,將v2版本的權(quán)重設(shè)置為50%,這個(gè)百分比并不能精確的將請(qǐng)求平均分配到兩個(gè)版本的服務(wù),而是在50%上下浮動(dòng)
apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:: nginx: "true": "50"labels:app: echoserverv2name: echoserverv2namespace: echoserverspec:rules:host: echo.chulinx.comhttp:paths:backend:serviceName: echoserverv2servicePort: 8080path: /---kind: ServiceapiVersion: v1metadata:name: echoserverv2namespace: echoserverspec:selector:name: echoserverv2type: ClusterIPports:name: echoserverv2port: 8080targetPort: 8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: echoserverv2namespace: echoserverlabels:name: echoserverv2spec:template:metadata:labels:name: echoserverv2spec:containers:image: mirrorgooglecontainers/echoserver:1.10name: echoserverv2ports:containerPort: 8080name: echoserverv2
創(chuàng)建v2版本的服務(wù)
我們開(kāi)啟canary功能,將v2版本的權(quán)重設(shè)置為50%,這個(gè)百分比并不能精確的將請(qǐng)求平均分配到兩個(gè)版本的服務(wù),而是在50%上下浮動(dòng)
apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:: nginx: "true": "50"labels:app: echoserverv2name: echoserverv2namespace: echoserverspec:rules:host: echo.chulinx.comhttp:paths:backend:serviceName: echoserverv2servicePort: 8080path: /---kind: ServiceapiVersion: v1metadata:name: echoserverv2namespace: echoserverspec:selector:name: echoserverv2type: ClusterIPports:name: echoserverv2port: 8080targetPort: 8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: echoserverv2namespace: echoserverlabels:name: echoserverv2spec:template:metadata:labels:name: echoserverv2spec:containers:image: mirrorgooglecontainers/echoserver:1.10name: echoserverv2ports:containerPort: 8080name: echoserverv2
再次查看創(chuàng)建的資源
[K8sSj] kubectl get pod,service,ingress -n echoserverNAME READY STATUS RESTARTS AGE1/1 Running 0 24h1/1 Running 0 4sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEClusterIP 10.99.68.728080/TCP 24h ClusterIP 10.111.103.1708080/TCP 4s NAME HOSTS ADDRESS PORTS AGEecho.chulinx.com 80 24hecho.chulinx.com 80 4s
訪問(wèn)測(cè)試
可以看到請(qǐng)求有4個(gè)落到v2版本,6個(gè)落到v1版本,理論上來(lái)說(shuō),請(qǐng)求說(shuō)越多,落到v2版本的請(qǐng)求數(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測(cè)試
更改v2版本的編排文件
增加header
nginx.ingress.kubernetes.io/canary-by-header: "v2"
apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:: nginx: "true": "50": "v2"labels:app: echoserverv2name: echoserverv2namespace: echoserverspec:rules:host: echo.chulinx.comhttp:paths:backend:serviceName: echoserverv2servicePort: 8080path: /---kind: ServiceapiVersion: v1metadata:name: echoserverv2namespace: echoserverspec:selector:name: echoserverv2type: ClusterIPports:name: echoserverv2port: 8080targetPort: 8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: echoserverv2namespace: echoserverlabels:name: echoserverv2spec:template:metadata:labels:name: echoserverv2spec:containers:image: mirrorgooglecontainers/echoserver:1.10name: echoserverv2ports:containerPort: 8080name: echoserverv2
更新訪問(wèn)測(cè)試
測(cè)試了header 為
v2:always?v2:never?v2:true這三個(gè)hearder值,可以看到當(dāng)hearder為v2:always時(shí),流量會(huì)全部流入v2,當(dāng)v2:never時(shí),流量會(huì)全部流入v1,當(dāng)v2:true時(shí),也就是非always/never,流量會(huì)按照配置的權(quán)重流入對(duì)應(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:: nginx: "true": "50": "v2": "true"labels:app: echoserverv2name: echoserverv2namespace: echoserverspec:rules:host: echo.chulinx.comhttp:paths:backend:serviceName: echoserverv2servicePort: 8080path: /---kind: ServiceapiVersion: v1metadata:name: echoserverv2namespace: echoserverspec:selector:name: echoserverv2type: ClusterIPports:name: echoserverv2port: 8080targetPort: 8080---apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: echoserverv2namespace: echoserverlabels:name: echoserverv2spec:template:metadata:labels:name: echoserverv2spec:containers:image: mirrorgooglecontainers/echoserver:1.10name: echoserverv2ports:containerPort: 8080name: echoserverv2
更新測(cè)試
可以看到只有header為 v2:never時(shí),請(qǐng)求流量才會(huì)流入v2版本,其他值流量都會(huì)按照權(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
訪問(wèn)測(cè)試
可以看和header的訪問(wèn)效果是一樣的,只不過(guò)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)定,在初始灰度的時(shí)候就可以對(duì)新版本進(jìn)行測(cè)試、發(fā)現(xiàn)和調(diào)整問(wèn)題,以保證其影響度,以上內(nèi)容通過(guò)實(shí)例詳細(xì)介紹了Ingress-Nginx的實(shí)戰(zhàn)Canary Annotation,可以借助Ingress-Nginx輕松實(shí)現(xiàn)藍(lán)綠發(fā)布和金絲雀發(fā)布
其他
關(guān)于藍(lán)綠發(fā)布、金絲雀發(fā)布、和A/B測(cè)試
藍(lán)綠發(fā)布
藍(lán)綠部署中,一共有兩套系統(tǒng):一套是正在提供服務(wù)系統(tǒng),標(biāo)記為“綠色”;另一套是準(zhǔn)備發(fā)布的系統(tǒng),標(biāo)記為“藍(lán)色”。兩套系統(tǒng)都是功能完善的,并且正在運(yùn)行的系統(tǒng),只是系統(tǒng)版本和對(duì)外服務(wù)情況不同。 最初,沒(méi)有任何系統(tǒng),沒(méi)有藍(lán)綠之分。 然后,第一套系統(tǒng)開(kāi)發(fā)完成,直接上線,這個(gè)過(guò)程只有一個(gè)系統(tǒng),也沒(méi)有藍(lán)綠之分。 后來(lái),開(kāi)發(fā)了新版本,要用新版本替換線上的舊版本,在線上的系統(tǒng)之外,搭建了一個(gè)使用新版本代碼的全新系統(tǒng)。這時(shí)候,一共有兩套系統(tǒng)在運(yùn)行,正在對(duì)外提供服務(wù)的老系統(tǒng)是綠色系統(tǒng),新部署的系統(tǒng)是藍(lán)色系統(tǒng)。 藍(lán)色系統(tǒng)不對(duì)外提供服務(wù),用來(lái)做啥? 用來(lái)做發(fā)布前測(cè)試,測(cè)試過(guò)程中發(fā)現(xiàn)任何問(wèn)題,可以直接在藍(lán)色系統(tǒng)上修改,不干擾用戶正在使用的系統(tǒng)。(注意,兩套系統(tǒng)沒(méi)有耦合的時(shí)候才能百分百保證不干擾) 藍(lán)色系統(tǒng)經(jīng)過(guò)反復(fù)的測(cè)試、修改、驗(yàn)證,確定達(dá)到上線標(biāo)準(zhǔn)之后,直接將用戶切換到藍(lán)色系統(tǒng): 切換后的一段時(shí)間內(nèi),依舊是藍(lán)綠兩套系統(tǒng)并存,但是用戶訪問(wèn)的已經(jīng)是藍(lán)色系統(tǒng)。這段時(shí)間內(nèi)觀察藍(lán)色系統(tǒng)(新系統(tǒng))工作狀態(tài),如果出現(xiàn)問(wèn)題,直接切換回綠色系統(tǒng)。 當(dāng)確信對(duì)外提供服務(wù)的藍(lán)色系統(tǒng)工作正常,不對(duì)外提供服務(wù)的綠色系統(tǒng)已經(jīng)不再需要的時(shí)候,藍(lán)色系統(tǒng)正式成為對(duì)外提供服務(wù)系統(tǒng),成為新的綠色系統(tǒng)。原先的綠色系統(tǒng)可以銷(xiāo)毀,將資源釋放出來(lái),用于部署下一個(gè)藍(lán)色系統(tǒng)。 藍(lán)綠部署只是上線策略中的一種,它不是可以應(yīng)對(duì)所有情況的萬(wàn)能方案。藍(lán)綠部署能夠簡(jiǎn)單快捷實(shí)施的前提假設(shè)是目標(biāo)系統(tǒng)是非常內(nèi)聚的,如果目標(biāo)系統(tǒng)相當(dāng)復(fù)雜,那么如何切換、兩套系統(tǒng)的數(shù)據(jù)是否需要以及如何同步等,都需要仔細(xì)考慮。
金絲雀發(fā)布
金絲雀發(fā)布(Canary)也是一種發(fā)布策略,和國(guó)內(nèi)常說(shuō)的灰度發(fā)布是同一類(lèi)策略。藍(lán)綠部署是準(zhǔn)備兩套系統(tǒng),在兩套系統(tǒng)之間進(jìn)行切換,金絲雀策略是只有一套系統(tǒng),逐漸替換這套系統(tǒng)
譬如說(shuō),目標(biāo)系統(tǒng)是一組無(wú)狀態(tài)的Web服務(wù)器,但是數(shù)量非常多,假設(shè)有一萬(wàn)臺(tái)。
這時(shí)候,藍(lán)綠部署就不能用了,因?yàn)槟悴豢赡苌暾?qǐng)一萬(wàn)臺(tái)服務(wù)器專(zhuān)門(mén)用來(lái)部署藍(lán)色系統(tǒng)(在藍(lán)綠部署的定義中,藍(lán)色的系統(tǒng)要能夠承接所有訪問(wèn))。可以想到的一個(gè)方法是:
只準(zhǔn)備幾臺(tái)服務(wù)器,在上面部署新版本的系統(tǒng)并測(cè)試驗(yàn)證。測(cè)試通過(guò)之后,擔(dān)心出現(xiàn)意外,還不敢立即更新所有的服務(wù)器。先將線上的一萬(wàn)臺(tái)服務(wù)器中的10臺(tái)更新為最新的系統(tǒng),然后觀察驗(yàn)證。確認(rèn)沒(méi)有異常之后,再將剩余的所有服務(wù)器更新。
這個(gè)方法就是金絲雀發(fā)布。實(shí)際操作中還可以做更多控制,譬如說(shuō),給最初更新的10臺(tái)服務(wù)器設(shè)置較低的權(quán)重、控制發(fā)送給這10臺(tái)服務(wù)器的請(qǐng)求數(shù),然后逐漸提高權(quán)重、增加請(qǐng)求數(shù)。
這個(gè)控制叫做“流量切分”,既可以用于金絲雀發(fā)布,也可以用于后面的A/B測(cè)試。
藍(lán)綠部署和金絲雀發(fā)布是兩種發(fā)布策略,都不是萬(wàn)能的。有時(shí)候兩者都可以使用,有時(shí)候只能用其中一種。
A/B測(cè)試
首先需要明確的是,A/B測(cè)試和藍(lán)綠部署以及金絲雀,完全是兩回事。
藍(lán)綠部署和金絲雀是發(fā)布策略,目標(biāo)是確保新上線的系統(tǒng)穩(wěn)定,關(guān)注的是新系統(tǒng)的BUG、隱患。
A/B測(cè)試是效果測(cè)試,同一時(shí)間有多個(gè)版本的服務(wù)對(duì)外服務(wù),這些服務(wù)都是經(jīng)過(guò)足夠測(cè)試,達(dá)到了上線標(biāo)準(zhǔn)的服務(wù),有差異但是沒(méi)有新舊之分(它們上線時(shí)可能采用了藍(lán)綠部署的方式)。
A/B測(cè)試關(guān)注的是不同版本的服務(wù)的實(shí)際效果,譬如說(shuō)轉(zhuǎn)化率、訂單情況等。
A/B測(cè)試時(shí),線上同時(shí)運(yùn)行多個(gè)版本的服務(wù),這些服務(wù)通常會(huì)有一些體驗(yàn)上的差異,譬如說(shuō)頁(yè)面樣式、顏色、操作流程不同。相關(guān)人員通過(guò)分析各個(gè)版本服務(wù)的實(shí)際效果,選出效果最好的版本。
在A/B測(cè)試中,需要能夠控制流量的分配,譬如說(shuō),為A版本分配10%的流量,為B版本分配10%的流量,為C版本分配80%的流量。
- END -
公眾號(hào)后臺(tái)回復(fù)「加群」加入一線高級(jí)工程師技術(shù)交流群,一起交流進(jìn)步。
?推薦閱讀? 31天拿下Kubernetes CKA認(rèn)證! 2021最新 Kubernetes 運(yùn)維架構(gòu)師實(shí)戰(zhàn)指南? 一文搞懂藍(lán)綠發(fā)布、灰度發(fā)布和滾動(dòng)發(fā)布 Kubernetes 集群網(wǎng)絡(luò)從懵圈到熟悉 一篇文章搞懂日志采集利器 Filebeat Prometheus 監(jiān)控服務(wù)端口、網(wǎng)站狀態(tài)等(黑盒監(jiān)測(cè)) Kubernetes 學(xué)習(xí)筆記總結(jié),超詳細(xì)! Kubernetes生產(chǎn)環(huán)境最佳實(shí)踐
點(diǎn)亮,服務(wù)器三年不宕機(jī)


