istio 1.10学习笔记09: Istio流量管理之设置请求超时和熔断
前面幾節內容我們學習了Istio API資源對象中的虛擬服務VirtualService, 目標規則DestinationRule, Gateway。 使用它們可以實現將集群外部流量(http或tcp)接入到服務網格內部,可以進行一些常見的流量管理功能如: 設置請求路由、故障注入、流量轉移(http或tcp)等。 本節我們學習使用istio進行流量管理的另外兩個常見功能:設置請求超時和熔斷。
設置請求超時
對HTPP服務的請求超時,可以通過虛擬服務的路由規則中的timeout字段來指定。默認請求下這個配置是禁用的。 下面基于bookinfo應用完成這個測試。
本測試將reviews服務的超時設置為1秒,為了便于觀察測試結果,還將使用istio的故障注入功能為對ratings服務注入2秒的延遲故障。
首先執行下面的命令初始化bookinfo應用各服務的路由規則:
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
修改reviews服務的虛擬服務,將對reviews服務的請求全都路由到v2版本:
kubectl apply -f - <<eof apiversion:="" networking.istio.io="" v1alpha3="" kind:="" virtualservice="" metadata:="" name:="" reviews="" spec:="" hosts:="" -="" http:="" route:="" destination:="" host:="" subset:="" v2="" eof
對ratings服務進行故障注入,注入2秒的延遲:
kubectl apply -f - <<eof apiversion:="" networking.istio.io="" v1alpha3="" kind:="" virtualservice="" metadata:="" name:="" ratings="" spec:="" hosts:="" -="" http:="" fault:="" delay:="" percent:="" 100="" fixeddelay:="" 2s="" route:="" destination:="" host:="" subset:="" v1="" eof
此時使用我們之前配置好的Istio Gateway入口訪問bookinfo應用https://bookinfo.example.com/productpage,會發現bookinfo應用運行正常(顯示了評級的星型符號),但是每次刷新頁面,都會有2秒的延遲。
因為reviews:v2版本的服務是通過調用ratings服務獲取評級信息的,默認reviews服務默認是沒有設置請求超時的,所以它會等待ratings服務中注入的2秒延遲,每次刷新頁面也就有了2秒的延遲。
由于productpage服務中存在硬編碼重試,即遇到錯誤時會重試1次,下面我們將對review服務的調用設置一個0.5秒的超時:
kubectl apply -f - <<eof apiversion:="" networking.istio.io="" v1alpha3="" kind:="" virtualservice="" metadata:="" name:="" reviews="" spec:="" hosts:="" -="" http:="" route:="" destination:="" host:="" subset:="" v2="" timeout:="" 0.5s="" eof
此時再刷新/productpage頁,會有1秒的延遲,且頁面中的書籍評級信息出現錯誤Error fetching product reviews! 。這是因為這個請求的調用鏈如下productpage(出現請求超時錯誤時重試1次) --> reviews(請求超時設置為0.5秒) ---> ratings(注入了2秒的延遲)。可以看出通過設置對reviews服務的請求超時,實現了微服務治理中設置請求超時的功能,這完全是在服務網格中實現的,沒有侵入微服務的業務邏輯。 在服務治理中通過設置請求超時,可以避免大量請求長時間占用資源。
熔斷
熔斷熔斷是創建彈性微服務的重要模式,熔斷可以使應用程序具備應對來自故障、潛在峰值和其他未知網絡因素的能力。 熔斷機制是應對雪崩效應的一種微服務鏈路保護機制。服務雪崩是指當調用鏈中的某個環節,特別是服務提供方不可用時,將會導致上游環節不可用,并最終將這個影響擴大到整個系統中,導致整個系統的不可用。
下面將演示istio中流量管理的熔斷功能。
首先部署用于測試的httpbin應用,將其部署在k8s的default namespace內,因為default命名空間在前面部署bookinfo應用時已經開啟了istio sidecar的自動注入功能,所以這里直接部署httpbin應用即可:
kubectl apply -f samples/httpbin/httpbin.yaml
httpbin.yaml的內容如下:
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
再次看一下下圖中istio中虛擬服務和目標規則的關系,熔斷器的配置需要配置在目標規則上。
接下來創建一個目標規則,在調用httpbin時設置了熔斷器:
kubectl apply -f - <<eof apiversion:="" networking.istio.io="" v1alpha3="" kind:="" destinationrule="" metadata:="" name:="" httpbin="" spec:="" host:="" trafficpolicy:="" connectionpool:="" tcp:="" maxconnections:="" 1="" http:="" http1maxpendingrequests:="" maxrequestsperconnection:="" outlierdetection:="" consecutive5xxerrors:="" interval:="" 1s="" baseejectiontime:="" 3m="" maxejectionpercent:="" 100="" eof=""
在httpbin的目標規則的trafficPolicy中,定義了maxConnections: 1和http1MaxPendingRequests: 1。這表示如果并發的連接和請求數超過一個,在istio-proxy中進行進一步的請求和連接時,后續請求和連接將被阻止。
接下來在k8s的default命名空間內部署httpbin的客戶端程序fortio。fortio是專門用來做負載測試的,它可以控制連接數、并發數以及發送HTTP請求的延遲。 因為default命名空間在前面部署bookinfo應用時已經開啟了istio sidecar的自動注入功能,所以這里直接部署即可:
kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
fortio-deploy.yaml的內容如下:
apiVersion: v1
kind: Service
metadata:
name: fortio
labels:
app: fortio
service: fortio
spec:
ports:
- port: 8080
name: http
selector:
app: fortio
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fortio-deploy
spec:
replicas: 1
selector:
matchLabels:
app: fortio
template:
metadata:
annotations:
# This annotation causes Envoy to serve cluster.outbound statistics via 15000/stats
# in addition to the stats normally served by Istio. The Circuit Breaking example task
# gives an example of inspecting Envoy stats.
sidecar.istio.io/statsInclusionPrefixes: cluster.outbound,cluster_manager,listener_manager,http_mixer_filter,tcp_mixer_filter,server,cluster.xds-grpc
labels:
app: fortio
spec:
containers:
- name: fortio
image: fortio/fortio:latest_release
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http-fortio
- containerPort: 8079
name: grpc-ping
進入fortio的pod中測試一下,下面的命令將從fortio中向httpbin發一次請求,如果返回200請求成功則說明fortio部署完成,可以進行接下來的熔斷測試:
FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD -c fortio /usr/bin/fortio -- load -curl http://httpbin:8000/get
下面在fortio中向httpbin發送并發數為2的連接(-c 2),請求20次(-n 20):
FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
......
Code 200 : 13 (65.0 %)
Code 503 : 7 (35.0 %)
......
可以看到有35%的請求被熔斷器攔截,返回了503錯誤。而HTTP503錯誤表示服務不可用,通常造成這種情況的原因是由于服務器停機維護或者已超載,返回這個狀態碼也是十分合適的。
接下來將并發連接數提高到3個,請求20次:
FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
Code 200 : 2 (10.0 %)
Code 503 : 18 (90.0 %)
可以看到只有10%的請求成功,有90%的請求被熔斷器攔截。
參考
https://istio.io/latest/zh/docs/tasks/traffic-management/request-timeouts/https://istio.io/latest/docs/tasks/traffic-management/circuit-breaking/https://istio.io/latest/zh/docs/tasks/traffic-management/circuit-breaking/
總結
以上是生活随笔為你收集整理的istio 1.10学习笔记09: Istio流量管理之设置请求超时和熔断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新款 iPad Pro 和 Apple
- 下一篇: 升级iOS 12.1后iPhone X