> Retries 是在服務請求的過程中産生異常後最簡單的處理方法,就是讓服務再次重試,通過重試可以提供服務的可用性和健壯性。
#### 什麼場景需要用到重試
重試是解決很多請求異常最直接、簡單的方法,尤其是在工作環境比較複雜的場景下,克提高總體的服務品質。重試使用不當也會有問題,最糟糕的情況是重試一直不成功,反而增加延遲和性能開銷。是以根據系統運作環境、服務自身特點,配置适當的重試規則顯得尤為重要。
#### 通過例子來了解
nginx 服務通路 httpd 服務,但 httpd 服務由于自身故障錯誤響應 nginx 服務,nginx 服務為了提高容錯率則在等待了15秒之後重新發起第一次重試,如果還是為有響應,則在試第二次,如果還是沒有響應則請求失敗。在大多數場景下,由于故障不是恒定的,而是瞬時出現而後自動恢複的,則可以通過重試去提供服務的可用性。apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deployment
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx-deployment
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- image: 'nginx:latest'
name: nginx-deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: httpd-deployment
name: httpd-deployment
spec:
replicas: 1
selector:
matchLabels:
app: httpd-deployment
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: httpd-deployment
spec:
containers:
- image: 'httpd:latest'
name: httpd-deployment
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx-deployment
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: httpd-service
spec:
selector:
app: httpd-deployment
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
spec:
hosts:
- nginx-service
http:
- route:
- destination:
host: nginx-service
retries:
attempts: 3
perTryTimeout: 5s
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpd-vs
spec:
hosts:
- httpd-service
http:
- fault:
abort:
percentage:
value: 100
httpStatus: 503
route:
- destination:
host: httpd-service
```
##### 配置 nginx 反向代理 httpd 以完成上下遊調用的效果
kubectl exec -it nginx-deployment-56c94b9957-xgw88 -- sh
tee /etc/nginx/conf.d/default.conf <<-'EOF'
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://httpd-service;
proxy_http_version 1.1;
}
}
EOF
nginx -t ; nginx -s reload
##### 進入用戶端容器測試
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: client-deployment
name: client-deployment
spec:
replicas: 1
selector:
matchLabels:
app: client-deployment
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: client-deployment
spec:
containers:
- image: 'busybox:latest'
name: client-deployment
command: [ "/bin/sh", "-c", "sleep 3600"]
通過 ``kubectl exec -it client-deployment-56c94b9957-xgw88 -- sh`` 進入容器
執行 ``wget -q -O - http://nginx-service`` 測試
執行 ``kubectl logs -f nginx-deployment-86684f9cf6-lvxtj -c istio-proxy -n demo`` 觀測邊車日志
本身請求一次,加上三次重試
#### 重試相關參數配置
##### retries 參數
可以定義請求失敗時的政策,重試政策包括重試次數、逾時、重試條件
attempts: 必選字段,定義重試的次數
perTryTimeout: 單次重試逾時的時間,機關可以是ms、s、m和h
retryOn: 重試的條件,可以是多個條件,以逗号分隔
##### retryOn 參數
5xx:在上遊服務傳回5xx應答碼,或者在沒有傳回時重試
gateway-error:類似于5xx異常,隻對502、503和504應答碼進行重試
connect-failure:在連結上遊服務失敗時重試
retriable-4xx:在上遊服務傳回可重試的4xx應答碼時執行重試
refused-stream:在上遊服務使用REFUSED_STREAM錯誤碼重置時執行重試
cancelled:gRPC應答的Header中狀态碼是cancelled時執行重試
deadline-exceeded:在gRPC應答的Header中狀态碼是deadline-exceeded時執行重試
internal:在gRPC應答的Header中狀态碼是internal時執行重試
resource-exhausted:在gRPC應答的Header中狀态碼是resource-exhausted時執行重試
unavailable:在gRPC應答的Header中狀态碼是unavailable時執行重試。