天天看點

Istio - TrafficManagement - Retries

> Retries 是在服務請求的過程中産生異常後最簡單的處理方法,就是讓服務再次重試,通過重試可以提供服務的可用性和健壯性。

#### 什麼場景需要用到重試

重試是解決很多請求異常最直接、簡單的方法,尤其是在工作環境比較複雜的場景下,克提高總體的服務品質。重試使用不當也會有問題,最糟糕的情況是重試一直不成功,反而增加延遲和性能開銷。是以根據系統運作環境、服務自身特點,配置适當的重試規則顯得尤為重要。

#### 通過例子來了解

Istio - TrafficManagement - 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`` 測試

Istio - TrafficManagement - Retries

執行 ``kubectl logs -f nginx-deployment-86684f9cf6-lvxtj -c istio-proxy -n demo`` 觀測邊車日志

Istio - TrafficManagement - Retries

本身請求一次,加上三次重試

#### 重試相關參數配置

##### 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時執行重試。

繼續閱讀