Istio實踐(4)- 故障注入、熔斷及ServiceEntry

xjk27400861發表於2022-04-24

前言:接上一篇istio多服務應用部署及呼叫,本文介紹通過流量管理(故障注入、請求超時等)以及ServiceEntry外部服務部署應用

1.設定服務延遲

  • 修改springbootapp-vs-v1.yaml檔案,設定springbootapp服務應用100延遲,延遲時間為3s,percent指定超時比例100%
    image
  • 通過ingressgateway對外開放埠,訪問springbootapp服務,發現響應時間為3s
    image

2.設定服務超時

  • 修改springbootapp-vs-v1.yaml檔案,設定netcoreapp服務超時時間為2s
    image
  • 通過netcoreapp服務,呼叫springbootapp服務,由於springbootapp服務100%有3s延遲,那麼netcoreapp服務反饋超時錯誤
    image

3.故障注入(注入 HTTP abort 故障)

  • 修改springbootapp-vs-v1.yaml檔案,設定springbootapp服務abort
    image
  • 通過netcoreapp服務,呼叫springbootapp服務
    image
    image

4.配置熔斷器(DestinationRule)

  • 概念:
    1.熔斷的基本邏輯就是隔離故障。在微服務架構盛行的今天,服務之間的呼叫鏈路相比單體應用時代變得更長了,服務化拆分帶來系統整體能力提升的同時,也增加了服務級聯故障出現的概率。例如呼叫鏈路“A->B->C->D”,如果服務D出現問題,那麼鏈路上的A、B、C都可能會出現問題,這一點也很好理解,因為出現故障的服務D,必然會在某個時間段內阻塞C->D的呼叫請求,並最終蔓延至整個鏈路。而服務連線資源又是有限的,這種增加的呼叫耗時,會逐步消耗掉整個鏈路中所有服務的可用執行緒資源,從而成為壓垮整個微服務體系的幕後黑手。
    2.限流。熔斷的主要目的是隔離故障,而引起故障的原因除了系統本身的問題外,還有一種可能就是請求量達到了系統處理能力的極限,後續新進入的請求會持續加重服務負載,最終導致資源耗盡,從而引起系統級聯故障、導致雪崩。而限流的目的就是拒絕多餘流量、保證服務整體負載始終處於合理水平。
    從限流範圍上看,微服務體系中的每個服務都可以根據自身情況設定合理的限流規則,例如呼叫鏈路“A->B->C->D”,B服務的承受力是1000QPS,如果超過該閥值,那麼超出的請求就會被拒絕,但這也容易引起A對B的熔斷,所以對於微服務設定限流規則的設定最好還是根據壓測結果確定。
  • 修改springbootapp-dr.yaml檔案

    image

      說明:
      1.maxConnections(最大連線數為1)、http1MaxPendingRequests(最大等待請求數為1),如果連線和併發請求數超過1個,那麼該服務就會觸發限流規則
      2.http1MaxPendingRequests: http 請求掛起狀態的最大請求數
      3.outlierDetection.consecutiveErrors: 拒絕連線的最大失敗次數
      4.outlierDetection.interval: 觸發熔斷的時間間隔,在 interval 時間間隔內,達到 consecutiveErrors 即觸發熔斷
      5.outlierDetection.baseEjectionTime: 熔斷時長
      6.maxEjectionPercent: 熔斷連線最大百分比
    
  • 使用壓測工具Fortio負載測試客戶端呼叫服務,我們這裡使用apifox工具(JMeter也可),進行壓測

    image

    image
    發現25%的請求成功,75%的請求失敗,限流成功,重複請求還是可以成功的

  • 加大併發次數和迴圈次數,觸發熔斷

    image

    image
    此時重複請求,發現總是失敗,沒有成功的情形,觸發了熔斷,由於我們設定熔斷時間3分鐘,我們等3分鐘後,再重試,就有成功的情形,測試成功
    image

5.服務條目(Service Entries)

  • 使用服務條目資源(Service Entries)可以將條目新增到 Istio 內部維護的服務登錄檔中。新增服務條目後,Envoy 代理可以將流量傳送到該服務,就好像該服務條目是網格中的服務一樣。通過配置服務條目,可以管理在網格外部執行的服務的流量。
  • 新建服務條目資源service-entry-baidu.yaml,指向百度
      apiVersion: networking.istio.io/v1alpha3
      kind: ServiceEntry
      metadata:
        name: baidu-entry
      spec:
        hosts:
        - "www.baidu.com"
        ports:
        - number: 80
          name: http
          protocol: HTTP
        location: MESH_EXTERNAL
        resolution: DNS
    
  • 執行命令,把服務條目放到netistiodemo的名稱空間下
      sudo kubectl apply -f service-entry-baidu.yaml -n netistiodemo
      sudo kubectl get se -n netistiodemo
    
  • 使用busybox,訪問baidu

    image

  • 修改serviceentry檔案,設定了靜態域名解析的方式,並隨意給了一個IP來標識 baidu,這樣訪問baidu就失敗了;說明我們的serviceentry生效了

    image

    image

  • service entry 使用場景
    如果你需要呼叫外部合作方服務,該服務跟你的叢集毫無關係。這時通過服務條目,你可以將對方服務納入到自己的Istio網格之內,就像它本身存在你的叢集之內一樣,結合虛擬服務(virtual service)、目的地規則(destination rule)做更加精細的流量控制、失敗注入、重試等功能。
    個人感覺也可以把以前的老專案,整體暴露給Istio網格;比如spring cloud、dubbo、netcore等等已執行部署的服務,通過service entry的方式,納入到Istio中管理
    能力有限,如有不妥之處,望見諒

相關文章