【问题标题】:How to configure fallbacks in envoyproxy?如何在 envoyproxy 中配置回退?
【发布时间】:2019-11-16 19:32:51
【问题描述】:

我正在尝试将 envoy 配置为负载均衡器,目前遇到回退问题。在我的游乐场集群中,我有 3 个后端服务器和特使作为前端代理。我正在使用 siege 和观察响应在特使上产生一些流量。在执行此操作时,我会停止其中一个后端。

我想要什么: Envoy 应该将失败的请求从停止的后端重新发送到健康的后端,这样我就不会收到任何 5xx 响应

我得到了什么:停止后端时,我收到一些 503 响应,然后一切又恢复正常

我做错了什么?我认为,fallback_policy 应该提供这个功能,但它不起作用。

这是我的配置文件:

node:
  id: LoadBalancer_01
  cluster: HighloadCluster
admin:
  access_log_path: /var/log/envoy/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
  listeners:
    - name: http_listener
      address:
        socket_address: { address: 0.0.0.0, port_value: 80 }
      filter_chains:
        - filters:
            - name: envoy.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
                stat_prefix: ingress_http
                codec_type: AUTO
                route_config:
                  name: request_route
                  virtual_hosts:
                    - name: local_service
                      domains: ["*"]
                      require_tls: NONE
                      routes:
                        - match: { prefix: "/" }
                          route:
                            cluster: backend_service
                            timeout: 1.5s
                          retry_policy:
                            retry_on: 5xx
                            num_retries: 3
                            per_try_timeout: 3s
                http_filters:
                  - name: envoy.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router
                      name: envoy.file_access_log
                      typed_config:
                        "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog
                        path: /var/log/envoy/access.log
  clusters:
    - name: backend_service
      connect_timeout: 0.25s
      type: STATIC
      lb_policy: ROUND_ROBIN
      lb_subset_config:
        fallback_policy: ANY_ENDPOINT
      outlier_detection:
        consecutive_5xx: 1
        interval: 10s
      load_assignment:
        cluster_name: backend_service
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: 1.1.1.1
                      port_value: 10000
              - endpoint:
                  address:
                    socket_address:
                      address: 2.2.2.2
                      port_value: 10000
              - endpoint:
                  address:
                    socket_address:
                      address: 3.3.3.3
                      port_value: 10000
      health_checks:
          - http_health_check:
              path: /api/liveness-probe
            timeout: 1s
            interval: 30s
            unhealthy_interval: 10s
            unhealthy_threshold: 2
            healthy_threshold: 1
            always_log_health_check_failures: true
            event_log_path: /var/log/envoy/health_check.log```

【问题讨论】:

    标签: configuration envoyproxy


    【解决方案1】:

    TL;DR

    您可以使用circuit breaker(请参见下面的配置示例)以及您的retry_policyoutlier_detection

    说明

    上下文

    我已成功重现您的配置问题(health_checks 部分除外,因为我发现重现您的问题没有用处)。

    我已经运行了 envoy 和我的后端(2 个应用程序负载平衡),产生了一些使用 hey 的流量(50 个线程在 10 秒内同时发出请求):

    hey -c 50 -z 10s http://envoy:8080
    

    并且我在命令启动后大约 5 秒停止了一个后端应用程序。

    结果

    在深入了解 envoy admin /stats 端点时,我发现了一些有趣的东西:

    cluster.backend_service.upstream_rq_200: 17899
    cluster.backend_service.upstream_rq_503: 28
    
    cluster.backend_service.upstream_rq_retry_overflow: 28
    cluster.backend_service.upstream_rq_retry_success: 3
    cluster.backend_service.upstream_rq_total: 17930
    

    当我停止一个后端应用程序时,确实有 28 个503 响应。但是重试以某种方式起作用:3 次重试成功(upstream_rq_retry_success),但其他 28 次重试失败(upstream_rq_retry_overflow),导致503 错误。为什么?

    来自cluster stats docs

    upstream_rq_retry_overflow:由于断路或超出重试预算而未重试的请求总数

    修复

    为了解决这个问题,我们可以在集群中添加一个断路器(我已经慷慨地使用了max_requestsmax_pending_requestsmax_retries 参数作为示例)。有趣的部分是retry_budget.budget_percent 值:

      clusters:
      - name: backend_service
        connect_timeout: 0.25s
        type: STRICT_DNS
        lb_policy: ROUND_ROBIN
        outlier_detection:
          consecutive_5xx: 1
          interval: 10s
        circuit_breakers:
          thresholds:
          - priority: "DEFAULT"
            max_requests: 0xffffffff
            max_pending_requests: 0xffffffff
            max_retries: 0xffffffff
            retry_budget:
              budget_percent:
                value: 100.0
    

    来自retry_budget docs

    budget_percent:将并发重试限制指定为活动请求和活动挂起请求之和的百分比。例如,如果有 100 个活动请求并且budget_percent 设置为 25,则可能有 25 次活动重试。

    此参数是可选的。默认为 20%。

    我将其设置为 100.0 以允许 100% 的活动重试。

    当使用这个新配置再次运行示例时,不再有upstream_rq_retry_overflow,因此不再有503 错误:

    cluster.backend_service.upstream_rq_200: 17051
    
    cluster.backend_service.upstream_rq_retry_overflow: 0
    cluster.backend_service.upstream_rq_retry_success: 5
    cluster.backend_service.upstream_rq_total: 17056
    

    注意如果遇到upstream_rq_retry_limit_exceeded,可以尝试设置并增加retry_budget.min_retry_concurrency(未设置时默认为3):

            retry_budget:
              budget_percent:
                value: 100.0
              min_retry_concurrency: 10
    

    【讨论】:

      猜你喜欢
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      • 1970-01-01
      • 2017-10-25
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多