天天看點

Envoy 上遊叢集斷路器

雪崩效應

  • 多級服務排程用場景中,某上遊服務因網絡故障或服務繁忙無法響應請求時很可能會導緻多級上遊調用者大規模級聯故障,進而導緻整個系統不可用,此即為服務的雪崩效應;
  • 服務雪崩效應是一種因“服務提供者”的不可用導緻“服務消費者”的不可用,并将不可用逐漸放大的過程;
  • 服務網格之上的微服務應用中,多級調用的長調用鍊并不鮮見;

熔斷

  • 熔斷:上遊服務(被調用者,即服務提供者)因壓力過大而變得響應過慢甚至失敗時,下遊服務(服務消費者)通過暫時切斷對上遊的請求調用達到犧牲局部,保全上遊甚至是整體之目的;
  • 熔斷打開(Open):在固定時間視窗内,檢測到的失敗名額達到指定的門檻值時啟動熔斷;
  • 所有請求會直接失敗而不再發往後端端點;
  • 熔斷半打開(Half Open):斷路器在工作一段時間後自動切換至半打開狀态,并根據下一次請求的傳回結果判定狀态切換;
  • 請求成功:轉為熔斷關閉狀态;
  • 請求失敗:切回熔斷打開狀态;
  • 熔斷關閉(Closed):一定時長後上遊服務可能會變得再次可用,此時下遊即可關閉熔斷,并再次請求其服務;
  • 總結起來, 熔斷是分布式應用常用的一種流量管理模式,它能夠讓應用程式免受上遊服務失敗、延遲峰值或其它網絡異常的侵害;
  • Envoy在網絡級别強制進行斷路限制,于是不必獨立配置和編碼每個應用;
Envoy 上遊叢集斷路器

Envoy斷路器

  • Envoy支援多種類型的完全分布式斷路機制,達到由其定義的門檻值時,相應的斷路器即會溢出:
  • 叢集最大連接配接數:Envoy同上遊叢集建立的最大連接配接數。如果此斷路器溢出,叢集的upstream_cx_overflow計數器将增加。cluster maximum connections + (number of endpoints in a cluster) * (connection pools for the cluster);
  • 叢集最大請求數:在任何給定時間,叢集中所有主機的最大請求數。如果此斷路器溢出,叢集的upstream_rq_pending_overflow
  • 叢集可挂起的最大請求數:在等待連接配接池連接配接就緒時将排隊的最大請求數。每當沒有足夠的上遊連接配接可用以立即分派請求時,請求就會添加到待處理請求清單中。對于 HTTP/2 連接配接,如果未配置最大并發流 和每個連接配接的最大請求數,則所有請求将在同一連接配接上多路複用,是以隻有在尚未建立連接配接時才會觸發此斷路器。如果此斷路器溢出,叢集的 upstream_rq_pending_overflow計數器将增加。對于 HTTP/3,相當于 HTTP/2 的最大并發流是最大并發流。
  • 叢集最大活動并發重試次數:在任何給定時間,叢集中所有主機可以進行的最大重試次數。一般來說,我們建議使用重試預算;但是,如果首選靜态斷路,則應積極斷路重試。這樣可以允許對偶發性故障進行重試,但整體重試量不會爆炸并導緻大規模級聯故障。如果此斷路器溢出,則叢集的 upstream_rq_retry_overflow計數器将增加。
  • 叢集最大并發連接配接池:可以同時執行個體化的最大連接配接池數。
  • 每個斷路器都可在每個叢集及每個優先級的基礎上進行配置和跟蹤,它們可分别擁有各自不同的設定;
  • 注意:在Istio中,熔斷的功能通過連接配接池(連接配接池管理)和故障執行個體隔離(異常點檢測)進行定義,而Envoy的斷路器通常僅對應于Istio中的連接配接池功能;
  • 通過限制某個用戶端對目标服務的連接配接數、通路請求、隊列長度和重試次數等,避免對一個服務的過量通路;
  • 某個服務執行個體頻繁逾時或者出錯時交其昨時逐出,以避免影響整個服務;

熔斷器的常用名額(Istio上下文)

  • 連續錯誤響應個數:在一個檢查周期内,連續出現5xx錯誤的個數,例502、503狀态碼;
  • 檢查周期:将會對檢查周期内的響應碼進行篩選;
  • 隔離執行個體比例:上遊執行個體中,允許被隔離的最大比例;采用向上取整機制,假設有10個執行個體,13%則最多會隔離2個執行個體;
  • 最短隔離時間:執行個體第一次被隔離的時間,之後每次隔離時間為隔離次數與最短隔離時間的乘積;

斷路器配置格式

circuit_breakers: {...} # 熔斷相關的配置,可選;
  threasholds: [] # 适用于特定路由優先級的相關名額及門檻值的清單;
  - priority: ... # 目前斷路器适用的路由優先級;
    max_connections: ... # 可發往上遊叢集的最大并發連接配接數,僅适用于HTTP/1,預設為1024;超過指定數量的連接配接則将其短路;
    max_pending_requests: ... # 允許請求服務時的可挂起的最大請求數,預設為1024;;超過指定數量的連接配接則将其短路;
    max_requests: ... # Envoy可排程給上遊叢集的最大并發請求數,預設為1024;僅适用于HTTP/2
    max_retries: ... # 允許發往上遊叢集的最大并發重試數量(假設配置了retry_policy),預設為3;
    track_remaining: ... # 其值為true時表示将公布統計資料以顯示斷路器打開前所剩餘的資源數量;預設為false;
    max_connection_pools: ... # 每個叢集可同時打開的最大連接配接池數量,預設為無限制;
    retry_budget: ...         # 指定與活動請求數相關的并發重試限制。此參數是可選的。
      budget_percent: ...     
        value: ...          # 将并發重試限制指定為活動請求和活動挂起請求總和的百分比。例如,如果有 100 個活動請求并且budget_percent 設定為 25,則可能有 25 次活動重試。此參數是可選的。預設為 20%。  
      min_retry_concurrency: ...   # 指定重試預算允許的最小重試并發。活動重試次數的限制可能永遠不會低于此數量。此參數是可選的。預設為 3。
  per_host_thresholds:   # 适用于叢集中每個單獨主機的可選每主機限制。目前,每個主機的限制僅支援max_connections字段。      

斷路器配置示例

檢視代碼

admin:
  access_log_path: "/dev/null"
  address:
    socket_address: { address: 0.0.0.0, port_value: 9901 }

static_resources:
  listeners:
  - address:
      socket_address: { address: 0.0.0.0, port_value: 80 }
    name: listener_http
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/livez"
                route:
                  cluster: webcluster2
              - match:
                  prefix: "/"
                route:
                  cluster: webcluster1
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
  - name: webcluster1
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: webcluster1
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: webservice1
                port_value: 80
    circuit_breakers:
      thresholds:         
        max_connections: 1
        max_pending_requests: 1
        max_retries: 3

  - name: webcluster2
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: webcluster2
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: webservice2
                port_value: 80
    outlier_detection:
      interval: "1s"
      consecutive_5xx: "3"
      consecutive_gateway_failure: "3"
      base_ejection_time: "10s"
      enforcing_consecutive_gateway_failure: "100"
      max_ejection_percent: "30"
      success_rate_minimum_hosts: "2"      

微服務環境壓測工具

  • 工具介紹
  • ​​https://github.com/fortio/fortio​​
  • fortio load -c 2 -qps 0 -n 20 -loglevel Warning URL

參考文檔

​​https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/circuit_breaking​​

繼續閱讀