微服务应用实现无损上下线实践
簡介:本文是阿里云微服務引擎MSE在應用發布時提供的無損上下線和服務預熱能力最佳實踐介紹。
本文是阿里云微服務引擎MSE在應用發布時提供的無損上下線和服務預熱能力最佳實踐介紹。假設應用的架構由Zuul網關以及后端的微服務應用實例(Spring Cloud)構成。具體的后端調用鏈路有購物車應用A,交易中心應用B,庫存中心應用C,這些應用中的服務之間通過Nacos注冊中心實現服務注冊與發現。
前提條件
開啟 MSE 微服務治理
- 已創建Kubernetes集群,請參見創建Kubernetes托管版集群。
- 已開通MSE微服務治理專業版,請參見開通MSE微服務治理。
背景信息
很多用戶量大并發度高的應用系統為了避免發布過程中的流量有損一般選擇在流量較小的半夜發布,雖然這樣做有效果,但不可控導致背后的研發運維人員經常因為發布問題時常搞得半夜膽戰心驚,心力疲憊。基于此,阿里云微服務引擎MSE通過在應用發布過程中,通過應用下線主動實時注銷,應用上線健康就緒檢查與生命周期對齊以及服務預熱等技術手段所提供的微服務應用無損上下線發布功能,讓研發運維人員即使是在白天發布應用,也能風輕云淡。
準備工作
注意,本實踐所使用的 Agent 目前還在灰度中,需要對應用 Agent 進行灰度升級,升級文檔:灰度升級微服務治理Agent - 微服務引擎MSE - 阿里云
應用部署在不同的Region(暫時僅支持國內region)請使用對應的Agent下載地址:http://arms-apm-cn-[regionId].oss-cn-[regionId].aliyuncs.com/2.7.1.3-mse-beta/,注意替換地址中的[regionId],regionId是阿里云regionId,
例如Region北京Agent 地址為:http://arms-apm-cn-beijing.oss-cn-beijing.aliyuncs.com/2.7.1.3-mse-beta/
應用部署流量架構圖
流量壓力來源
在 spring-cloud-zuul應用中,每個 pod 具備并發為 10 的訪問本地 zuul 端口的 127.0.0.1:20000:/A/a 的http請求流量。可以通過環境變量 demo.qps 配置并發數。
部署 Demo 應用程序
將下面的內容保存到一個文件中,假設取名為 mse-demo.yaml,并執行 kubectl apply -f mse-demo.yaml 以部署應用到提前創建好的Kubernetes集群中(注意因為demo中有CronHPA任務,所以請先在集群中安裝 ack-kubernetes-cronhpa-controller 組件,具體在容器服務-Kubernetes->市場->應用目錄中搜索組件在測試集群中進行安裝),這里我們將要部署 Zuul,A, B 和 C 三個應用,其中 A、B 兩個應用分別部署一個基線版本和一個灰度版本,B應用的基線版本關閉了無損下線能力,灰度版本開啟了無損下線能力。C應用開啟了服務預熱能力,其中預熱時長為120秒。
# Nacos Server
---
apiVersion: apps/v1
kind: Deployment
metadata:
?labels:
? ?app: nacos-server
?name: nacos-server
spec:
?replicas: 1
?selector:
? ?matchLabels:
? ? ?app: nacos-server
?template:
? ?metadata:
? ? ?labels:
? ? ? ?app: nacos-server
? ?spec:
? ? ?containers:
? ? ?- env:
? ? ? ?- name: MODE
? ? ? ? ?value: standalone
? ? ? ?image: registry.cn-shanghai.aliyuncs.com/yizhan/nacos-server:latest
? ? ? ?imagePullPolicy: Always
? ? ? ?name: nacos-server
? ? ? ?resources:
? ? ? ? ?requests:
? ? ? ? ? ?cpu: 250m
? ? ? ? ? ?memory: 512Mi
? ? ?dnsPolicy: ClusterFirst
? ? ?restartPolicy: Always
# Nacos Server Service 配置
---
apiVersion: v1
kind: Service
metadata:
?name: nacos-server
spec:
?ports:
?- port: 8848
? ?protocol: TCP
? ?targetPort: 8848
?selector:
? ?app: nacos-server
?type: ClusterIP
#入口 zuul 應用
---
apiVersion: apps/v1
kind: Deployment
metadata:
?name: spring-cloud-zuul
spec:
?replicas: 1
?selector:
? ?matchLabels:
? ? ?app: spring-cloud-zuul
?template:
? ?metadata:
? ? ?annotations:
? ? ? ?msePilotCreateAppName: spring-cloud-zuul
? ? ?labels:
? ? ? ?app: spring-cloud-zuul
? ?spec:
? ? ?containers:
? ? ? ?- env:
? ? ? ? ? ?- name: JAVA_HOME
? ? ? ? ? ? ?value: /usr/lib/jvm/java-1.8-openjdk/jre
? ? ? ? ? ?- name: LANG
? ? ? ? ? ? ?value: C.UTF-8
? ? ? ? ?image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.1
? ? ? ? ?imagePullPolicy: Always
? ? ? ? ?name: spring-cloud-zuul
? ? ? ? ?ports:
? ? ? ? ? ?- containerPort: 20000
# A 應用 base 版本,開啟按照機器緯度全鏈路透傳
---
apiVersion: apps/v1
kind: Deployment
metadata:
?labels:
? ?app: spring-cloud-a
?name: spring-cloud-a
spec:
?replicas: 2
?selector:
? ?matchLabels:
? ? ?app: spring-cloud-a
?template:
? ?metadata:
? ? ?annotations:
? ? ? ?msePilotCreateAppName: spring-cloud-a
? ? ? ?msePilotAutoEnable: "on"
? ? ?labels:
? ? ? ?app: spring-cloud-a
? ?spec:
? ? ?containers:
? ? ?- env:
? ? ? ?- name: LANG
? ? ? ? ?value: C.UTF-8
? ? ? ?- name: JAVA_HOME
? ? ? ? ?value: /usr/lib/jvm/java-1.8-openjdk/jre
? ? ? ?- name: profiler.micro.service.tag.trace.enable
? ? ? ? ?value: "true"
? ? ? ?image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
? ? ? ?imagePullPolicy: Always
? ? ? ?name: spring-cloud-a
? ? ? ?ports:
? ? ? ?- containerPort: 20001
? ? ? ? ?protocol: TCP
? ? ? ?resources:
? ? ? ? ?requests:
? ? ? ? ? ?cpu: 250m
? ? ? ? ? ?memory: 512Mi
? ? ? ?livenessProbe:
? ? ? ? ?tcpSocket:
? ? ? ? ? ?port: 20001
? ? ? ? ?initialDelaySeconds: 10
? ? ? ? ?periodSeconds: 30
? ? ?
# A 應用 gray 版本,開啟按照機器緯度全鏈路透傳
--- ? ? ? ? ? ?
apiVersion: apps/v1
kind: Deployment
metadata:
?labels:
? ?app: spring-cloud-a-gray
?name: spring-cloud-a-gray
spec:
?replicas: 2
?selector:
? ?matchLabels:
? ? ?app: spring-cloud-a-gray
?strategy:
?template:
? ?metadata:
? ? ?annotations:
? ? ? ?alicloud.service.tag: gray
? ? ? ?msePilotCreateAppName: spring-cloud-a
? ? ? ?msePilotAutoEnable: "on"
? ? ?labels:
? ? ? ?app: spring-cloud-a-gray
? ?spec:
? ? ?containers:
? ? ?- env:
? ? ? ?- name: LANG
? ? ? ? ?value: C.UTF-8
? ? ? ?- name: JAVA_HOME
? ? ? ? ?value: /usr/lib/jvm/java-1.8-openjdk/jre
? ? ? ?- name: profiler.micro.service.tag.trace.enable
? ? ? ? ?value: "true"
? ? ? ?image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
? ? ? ?imagePullPolicy: Always
? ? ? ?name: spring-cloud-a-gray
? ? ? ?ports:
? ? ? ?- containerPort: 20001
? ? ? ? ?protocol: TCP
? ? ? ?resources:
? ? ? ? ?requests:
? ? ? ? ? ?cpu: 250m
? ? ? ? ? ?memory: 512Mi
? ? ? ?livenessProbe:
? ? ? ? ?tcpSocket:
? ? ? ? ? ?port: 20001
? ? ? ? ?initialDelaySeconds: 10
? ? ? ? ?periodSeconds: 30
? ? ? ? ? ?
# B 應用 base 版本,關閉無損下線能力
---
apiVersion: apps/v1
kind: Deployment
metadata:
?labels:
? ?app: spring-cloud-b
?name: spring-cloud-b
spec:
?replicas: 2
?selector:
? ?matchLabels:
? ? ?app: spring-cloud-b
?strategy:
?template:
? ?metadata:
? ? ?annotations:
? ? ? ?msePilotCreateAppName: spring-cloud-b
? ? ? ?msePilotAutoEnable: "on"
? ? ?labels:
? ? ? ?app: spring-cloud-b
? ?spec:
? ? ?containers:
? ? ?- env:
? ? ? ?- name: LANG
? ? ? ? ?value: C.UTF-8
? ? ? ?- name: JAVA_HOME
? ? ? ? ?value: /usr/lib/jvm/java-1.8-openjdk/jre
? ? ? ?- name: micro.service.shutdown.server.enable
? ? ? ? ?value: "false"
? ? ? ?- name: profiler.micro.service.http.server.enable
? ? ? ? ?value: "false"
? ? ? ?image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
? ? ? ?imagePullPolicy: Always
? ? ? ?name: spring-cloud-b
? ? ? ?ports:
? ? ? ?- containerPort: 8080
? ? ? ? ?protocol: TCP
? ? ? ?resources:
? ? ? ? ?requests:
? ? ? ? ? ?cpu: 250m
? ? ? ? ? ?memory: 512Mi
? ? ? ?livenessProbe:
? ? ? ? ?tcpSocket:
? ? ? ? ? ?port: 20002
? ? ? ? ?initialDelaySeconds: 10
? ? ? ? ?periodSeconds: 30
? ? ? ? ? ?
# B 應用 gray 版本,默認開啟無損下線功能
---
apiVersion: apps/v1
kind: Deployment
metadata:
?labels:
? ?app: spring-cloud-b-gray
?name: spring-cloud-b-gray
spec:
?replicas: 2
?selector:
? ?matchLabels:
? ? ?app: spring-cloud-b-gray
?template:
? ?metadata:
? ? ?annotations:
? ? ? ?alicloud.service.tag: gray
? ? ? ?msePilotCreateAppName: spring-cloud-b
? ? ? ?msePilotAutoEnable: "on"
? ? ?labels:
? ? ? ?app: spring-cloud-b-gray
? ?spec:
? ? ?containers:
? ? ?- env:
? ? ? ?- name: LANG
? ? ? ? ?value: C.UTF-8
? ? ? ?- name: JAVA_HOME
? ? ? ? ?value: /usr/lib/jvm/java-1.8-openjdk/jre
? ? ? ?image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
? ? ? ?imagePullPolicy: Always
? ? ? ?name: spring-cloud-b-gray
? ? ? ?ports:
? ? ? ?- containerPort: 8080
? ? ? ? ?protocol: TCP
? ? ? ?resources:
? ? ? ? ?requests:
? ? ? ? ? ?cpu: 250m
? ? ? ? ? ?memory: 512Mi
? ? ? ?lifecycle:
? ? ? ? ? ?preStop:
? ? ? ? ? ? ?exec:
? ? ? ? ? ? ? ?command:
? ? ? ? ? ? ? ? ?- /bin/sh
? ? ? ? ? ? ? ? ?- '-c'
? ? ? ? ? ? ? ? ?- >-
? ? ? ? ? ? ? ? ? ?wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep
? ? ? ? ? ? ? ? ? ?30;exit 0
? ? ? ?livenessProbe:
? ? ? ? ?tcpSocket:
? ? ? ? ? ?port: 20002
? ? ? ? ?initialDelaySeconds: 10
? ? ? ? ?periodSeconds: 30
? ? ? ? ? ?
# C 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
?labels:
? ?app: spring-cloud-c
?name: spring-cloud-c
spec:
?replicas: 2
?selector:
? ?matchLabels:
? ? ?app: spring-cloud-c
?template:
? ?metadata:
? ? ?annotations:
? ? ? ?msePilotCreateAppName: spring-cloud-c
? ? ? ?msePilotAutoEnable: "on"
? ? ?labels:
? ? ? ?app: spring-cloud-c
? ?spec:
? ? ?containers:
? ? ?- env:
? ? ? ?- name: LANG
? ? ? ? ?value: C.UTF-8
? ? ? ?- name: JAVA_HOME
? ? ? ? ?value: /usr/lib/jvm/java-1.8-openjdk/jre
? ? ? ?image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
? ? ? ?imagePullPolicy: Always
? ? ? ?name: spring-cloud-c
? ? ? ?ports:
? ? ? ?- containerPort: 8080
? ? ? ? ?protocol: TCP
? ? ? ?resources:
? ? ? ? ?requests:
? ? ? ? ? ?cpu: 250m
? ? ? ? ? ?memory: 512Mi
? ? ? ?livenessProbe:
? ? ? ? ?tcpSocket:
? ? ? ? ? ?port: 20003
? ? ? ? ?initialDelaySeconds: 10
? ? ? ? ?periodSeconds: 30
#HPA 配置
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
?labels:
? ?controller-tools.k8s.io: "1.0"
?name: spring-cloud-b
spec:
? scaleTargetRef:
? ? ?apiVersion: apps/v1beta2
? ? ?kind: Deployment
? ? ?name: spring-cloud-b
? jobs:
? - name: "scale-down"
? ? schedule: "0 0/5 * * * *"
? ? targetSize: 1
? - name: "scale-up"
? ? schedule: "10 0/5 * * * *"
? ? targetSize: 2
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
?labels:
? ?controller-tools.k8s.io: "1.0"
?name: spring-cloud-b-gray
spec:
? scaleTargetRef:
? ? ?apiVersion: apps/v1beta2
? ? ?kind: Deployment
? ? ?name: spring-cloud-b-gray
? jobs:
? - name: "scale-down"
? ? schedule: "0 0/5 * * * *"
? ? targetSize: 1
? - name: "scale-up"
? ? schedule: "10 0/5 * * * *"
? ? targetSize: 2
---
apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
?labels:
? ?controller-tools.k8s.io: "1.0"
?name: spring-cloud-c
spec:
? scaleTargetRef:
? ? ?apiVersion: apps/v1beta2
? ? ?kind: Deployment
? ? ?name: spring-cloud-c
? jobs:
? - name: "scale-down"
? ? schedule: "0 2/5 * * * *"
? ? targetSize: 1
? - name: "scale-up"
? ? schedule: "10 2/5 * * * *"
? ? targetSize: 2
# zuul 網關開啟 SLB 暴露展示頁面 ?
--- ? ?
apiVersion: v1
kind: Service
metadata:
?name: zuul-slb
spec:
?ports:
? ?- port: 80
? ? ?protocol: TCP
? ? ?targetPort: 20000
?selector:
? ?app: spring-cloud-zuul
?type: ClusterIP
# a 應用暴露 k8s service
---
apiVersion: v1
kind: Service
metadata:
?name: spring-cloud-a-base
spec:
?ports:
? ?- name: http
? ? ?port: 20001
? ? ?protocol: TCP
? ? ?targetPort: 20001
?selector:
? ?app: spring-cloud-a
---
apiVersion: v1
kind: Service
metadata:
?name: spring-cloud-a-gray
spec:
?ports:
? ?- name: http
? ? ?port: 20001
? ? ?protocol: TCP
? ? ?targetPort: 20001
?selector:
? ?app: spring-cloud-a-gray
# Nacos Server SLB Service 配置
---
apiVersion: v1
kind: Service
metadata:
?name: nacos-slb
spec:
?ports:
?- port: 8848
? ?protocol: TCP
? ?targetPort: 8848
?selector:
? ?app: nacos-server
?type: LoadBalancer
結果驗證一:無損下線功能
由于我們對spring-cloud-b跟spring-cloud-b-gray應用均開啟了定時HPA,模擬每5分鐘進行一次定時的擴縮容。
登錄MSE控制臺,進入微服務治理中心->應用列表->spring-cloud-a->應用詳情,從應用監控曲線,我們可以看到spring-cloud-a應用的流量數據:
gray版本的流量在pod擴縮容的過程中請求錯誤數為0,無流量損失。未打標的版本由于關閉了無損下線功能,在pod擴縮容的過程中有20個從spring-cloud-a發到spring-cloud-b的請求出現報錯,發生了請求流量損耗。
結果驗證二:服務預熱功能
我們在 spring-cloud-c 應用開啟了定時HPA 模擬應用啟動的過程,每隔5分鐘做一次伸縮,在第2分鐘第0秒縮容到1個節點,在第2分鐘第10秒擴容到2個節點。
在預熱應用的消費端 spring-cloud-b開啟服務預熱功能。
在預熱應用的服務提供端 spring-cloud-c開啟服務預熱功能。預熱時長配置為 120 秒。
觀察節點的流量,發現節點流量緩慢上升。并且能看到節點的預熱開始和結束時間,以及相關的事件。
從上圖可以看到開啟預熱功能的應用重啟后的流量會隨時間緩慢增加,在一些應用啟動過程中需要預建連接池和緩存等資源的慢啟動場景,開啟服務預熱能有效保護應用啟動過程中緩存資源有序創建保障應用安全啟動并做到流量無損。
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。?
總結
以上是生活随笔為你收集整理的微服务应用实现无损上下线实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宜搭小技巧|维护Excel太麻烦?Exc
- 下一篇: 解决 Serverless 落地困难的关