首页 > 其他分享 >Envoy 局部故障处理机制

Envoy 局部故障处理机制

时间:2022-09-06 16:12:57浏览次数:47  
标签:retry name envoy 局部 Envoy 重试 故障 address type

局部故障处理机制

  • retry:分布式环境中对远程资源和服务的调用可能会由于瞬态故障(短时间内可自行恢复的故障)而失败,一般情况下,重试机制可解决此类问题
    • 常见的瞬态故障有网络连接速度慢、超时、资源过量使用或暂时不可用等

  • timeout:此外,也存在因意外事件而导致故障,并且可能需要较长的时间才能得以恢复;

    • 此类故障的严重性范围涵盖从部分连接中断到服务完全失败;

      • 连续重试和长时间的等待对该类场景都没有太大意义

      • 应用程序应迅速接受该操作已失败并主动地应对该失败

    • 可以将调用服务的操作配置为实施“超时”,若该服务在超时时长内未能响应,则以失败消息响应

  • circuit breaker:还有,若服务非常繁忙,则系统某一部分的故障可能会导致级联故障;

    • 对此,简单的超时策略可能导致对同一操作的许多并发请求被阻止,直到超时时长耗尽为止;

    • 这些被阻止的请求可能包含关键的系统资源,例如内存、线程和数据库连接等

      • 这类资源的耗尽可能导致需要使用相同资源的系统其他可能不相关的部分出现故障

      • 于是,此时最好立即使操作失败,并且仅在可能成功的情况下才尝试调用服务

请求重试

  • 分布式应用环境中的瞬态故障并不鲜见

    • 常见的故障包括与组件和服务的网络连接的暂时丢失、服务暂时不可用或服务繁忙时发生的超时等

    • 这类故障通常能自我纠正,并且如果在适当的延迟后重复此前触发了故障的请求操作,则可能会成功

  • 通过透明地重试失败的操作,使应用程序在尝试连接到服务或网络资源时能够处理瞬态故障,可以显著提高应用程序的稳定性;
  • 常见的瞬态处理策略有如下三个

    • 重试:对于暂时性或不常见类型的故障,反复请求通常可以获得正确结果;

    • 延迟后重试:若故障是由较常见的连接故障或繁忙故障引起,通常需要一些时间纠正连接问题或清除积压工作,应用程序则应等待适当的时间,然后重试请求;
    • 取消:对于并非暂时性故障,或即便反复请求也不太可能成功的故障,则应用程序应取消该操作并报告异常;

  • 对于更常见的瞬态故障,应合理设定重试之间的时间间隔,以尽可能均匀地传播来自应用程序多个实例的请求,从而减少繁忙服务持续超载的机率
    • 显然,如果应用程序的许多实例因不断重试请求而使服务不堪重负,则恢复该服务将花费更长的时间
  • 可以在重试尝试之间增加延迟的方式重复此过程,直到尝试了最大数量的请求为止

    • 延迟可以增量或指数方式增加,具体取决于故障的类型以及在此期间得到纠正的可能性

请求重试的注意事项

  • 重试策略需要匹配应用程序的业务需求和故障的性质,对于某些非关键操作,最好是快速失败而不是重试几次并影响应用程序的吞吐量
    • 对于交互式Web应用程序,在较短的延迟后进行少量重试,而后向用户显示适当的消息,例如“请稍后重试”

    • 对于批处理应用,增加重试次数可能会更合适,但重试次数之间的延迟应成倍或指数级增加

  • 若大量重试后请求仍然失败,最好防止进一步的请求进入同一服务,并立即报告失败

    • 在一定的过期时长后,设定服务暂时允许一个或多个请求通过,以查看它们是否成功,这是断路器的功能

  • 还需要考虑操作幂等与否

    • 对于幂等性操作,重试本质上是安全的

    • 否则,重试可能导致该操作被执行多次,并产生意外的副作用

  • 请求可能会由于多种原因而失败,它们可能分别会引发不同的异常,重试策略应根据异常的类型调整两次重试之间的时间间隔
    • 有些异常可能是迅速可解决的故障

    • 有些异常则可能会持续更长时间

  • 确保所有重试代码已针对各种故障情况进行了全面测试,以检查它们是否不会严重影响应用程序的性能或可靠性,是否对服务和资源造成过多负担,是否产生竞争状况或瓶颈

HTTP请求重试

  • Envoy支持在虚拟主机及路由级别配置中以及通过特定请求的标头配置重试

    • 路由级别重试的优先级高于虚拟主机级别

  • 重试策略的相关属性包括重试次数和重试条件等

    • 最大重试次数:可重试的最大次数

      • 在每次重试之间使用指数退避算法

      • 单次重试操作有其超时时长

      • 所有重试都包含在整个请求的超时时长之内,以避免由于大量重试而导致的超长请求时间

    • 重试条件:是指进行重试的前提条件,例如网络故障、5xx类的响应码等

HTTP请求重试格式

retry_policy: {...} # 重试策略,优先于虚拟主机级别的重试策略;
  retry_on: ...     # 重试发生的条件,其功能同x-envoy-retry-on和x-envoy-retry-grpc-on标头相同;
  num_retries: {...}  # 重试次数,默认值为1,其功能同x-envoy-max-retries标头相同,但采用二者中配置的最大值;
  per_try_timeout: {...} # 每次重试时同上游端点建立连接的超时时长;
  per_try_idle_timeout: {...}  # 指定每次重试尝试(包括初始尝试)的上游空闲超时。此参数是可选的,如果不存在,则没有每次尝试空闲超时。
  retry_priority: {...}   # 配置重试优先级策略,用于在各优先级之间分配负载;
  retry_host_predicate: [] # 重试时使用的主机断言(predicate)列表,各断言用于拒绝主机;在选择重试主机时将参考该列表中的各断言,若存在任何谓词拒绝了该主机,则需要重新尝试选择其它主机
  retry_options_predicates: []
  host_selection_retry_max_attempts: ...  # 允许尝试重新选择主机的最大次数,默认为1;
  retriable_status_codes: []  # 除了retry_on指定的条件之外,用于触发重试操作的http状态码列表;
  retry_back_off: {...}  # 配置用于控制回退算法的参数,默认基本间隔为25ms,给定基本间隔B和重试次数N,重试的退避范围为 [0,(2^N−1)B),最大间隔默认为基本间隔(250ms)的10倍;
  rate_limited_retry_back_off: {...}  # 定义控制重试回退策略的参数;
  retriable_headers: []   # 触发重试的HTTP响应标头列表,上游端点的响应报文与列表中的任何标头匹配时将触发重试;
  retriable_request_headers: [] # 必须在用于重试的请求报文中使用的HTTP标头列表;

HTTP请求重试条件

  • 重试条件(同x-envoy-retry-on标头)

    • 5xx:上游主机返回5xx响应码,或者根本未予响应(断开/重置/读取超时)
    • gateway-error:网关错误,类似于5xx策略,但仅为502、503或504的应用进行重试
    • connection-failure:在TCP级别与上游服务建立连接失败时进行重试
    • retriable-4xx:上游服务器返回可重复的4xx响应码时进行重试
    • refused-stream:上游服器务使用REFUSED——STREAM错误码重置时进行重试
    • retriable-status-codes:上游服务器的响应码与重试策略或x-envoy-retriable-status-codes标头值中定义的响应码匹配时进行重试
    • reset:上游主机完全不响应时(disconnect/reset/read超时),Envoy将进行重试;
    • retriable-headers:如果上游服务器响应报文匹配重试策略或 x-envoy-retriable-header-names标头中包含的任何标头,则Envoy将尝试重试
    • envoy-ratelimited:标头中存在x-envoy-ratelimited时进行重试
  • 重试条件2(同x-envoy-retry-grpc-on标头)

    • cancelled:gRPC应答标头中的状态码是“cancelled”时进行重试
    • deadline-exceeded:gRPC应答标头中的状态码是“deadline-exceeded”时进行重试
    • internal:gRPC应答标头中的状态码是“internal”时进行重试
    • resource-exhausted:gRPC应答标头中的状态码是“resource-exhausted”时进行重试
    • unavailable:gRPC应答标头中的状态码是“unavailable”时进行重试
  • 默认情况下,Envoy不会进行任何类型的重试操作,除非明确定义

重试和超时机制配置示例

front-envoy.yaml

查看代码
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

layered_runtime:
  layers:
  - name: admin
    admin_layer: {}
       
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 80 }
    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
          stat_prefix: ingress_http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/service/blue"
                route:
                  cluster: blue_abort
                  retry_policy:
                    retry_on: "5xx"  # 响应码为5xx时,则进行重试,重试最大次数为3次;
                    num_retries: 3                  
              - match:
                  prefix: "/service/red"
                route:
                  cluster: red_delay
                  timeout: 1s         # 超时时长为1秒,长于1秒,则执行超时操作;
              - match:
                  prefix: "/service/green"
                route:
                  cluster: green
              - match:
                  prefix: "/service/colors"
                route:
                  cluster: mycluster
                  retry_policy:       # 超时和重试策略同时使用;
                    retry_on: "5xx"
                    num_retries: 3                  
                  timeout: 1s
          http_filters:
          - name: envoy.filters.http.router

  clusters:
  - name: red_delay
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: red_delay
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: service_red
                port_value: 80

  - name: blue_abort
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: blue_abort
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: service_blue
                port_value: 80

  - name: green
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: green
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: service_green
                port_value: 80

  - name: mycluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: mycluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: colored
                port_value: 80

service-envoy-sidecar-fault-injection-delay.yaml

查看代码
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

layered_runtime:
  layers:
  - name: admin
    admin_layer: {}
       
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 80 }
    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
          stat_prefix: ingress_http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: local_service
          http_filters:
          - name: envoy.filters.http.fault
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
              max_active_faults: 100
              delay:
                fixed_delay: 10s
                percentage:
                  numerator: 10    # 向10%的请求注入10秒钟的延迟
                  denominator: HUNDRED
          - name: envoy.filters.http.router
            typed_config: 
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
  - name: local_service
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    load_assignment:
      cluster_name: local_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8080

service-envoy-sidecar-fault-injection-abort.yaml

查看代码
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

layered_runtime:
  layers:
  - name: admin
    admin_layer: {}
       
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 80 }
    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
          stat_prefix: ingress_http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: local_service
          http_filters:
          - name: envoy.filters.http.fault
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
              max_active_faults: 100
              abort:
                http_status: 503
                percentage:
                  numerator: 10    # 向10%的请求注入503中断
                  denominator: HUNDRED
          - name: envoy.filters.http.router
            typed_config: 
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
  - name: local_service
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    load_assignment:
      cluster_name: local_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8080

重试插件

重试行为

  • 重试操作会触发重新选择目标主机

    • 重试期间选择主机与首次处理请求时选择主机的方式相同,具体的选择行为由调度策略决定

    • 重试插件为用户提供了配置重试期间重新选择主机的方式

Host Predicates

  • 用于拒绝重试选择一个主机的断言,任何主机匹配断言列表中的任何断言时将会被拒绝,并导致重试进行主机选择;
  • Envoy 支持以下内置host predicates
    • envoy.retry_host_predicates.previous_hosts:跟踪以前尝试过的主机,并拒绝已经尝试过的主机;

    • envoy.retry_host_predicates.omit_canary_hosts:拒绝任何标记为Canary的主机,其标记配置在端点的过滤器过滤的元数据中;

    • envoy.retry_host_predicates.omit_host_metadata:这将根据预定义的元数据匹配标准拒绝任何主机。

Priority Predicates

  • 用于调整重试尝试选择优先级时使用的优先级负载,此类断言仅能指定一个;

  • Envoy 支持以下内置priority predicates
    • envoy.retry_priority.previous_priorities:跟踪先前尝试的优先级,并据此调整优先级负载以便在后续的重试尝试中将其它优先级作为目标;

重试插件配置示例

  • 例如,要将重试配置为首选尚未尝试过的主机, 可以使用内置predicates:envoy.retry_host_predicates.previous_hosts
retry_policy:
  retry_host_predicate:
  - name: envoy.retry_host_predicates.previous_hosts
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
  host_selection_retry_max_attempts: 3

这将拒绝以前尝试过的主机,最多重试主机选择 3 次。为了处理不可能找到可接受的主机(没有主机满足predicates)或不太可能(唯一合适的主机具有非常低的相对权重)的情况,尝试限制是必要的。

  • 要根据其元数据拒绝主机,可以使用envoy.retry_host_predicates.omit_host_metadata
retry_policy:
  retry_host_predicate:
  - name: envoy.retry_host_predicates.omit_host_metadata
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.host.omit_host_metadata.v3.OmitHostMetadataConfig
      metadata_match:
        filter_metadata:
          envoy.lb:
            key: value

这将拒绝任何在其元数据中匹配(键、值)的主机。

  • 要配置重试以在重试期间尝试其他优先级,可以使用内置envoy.retry_priorities.previous_priorities
retry_policy:
  retry_priority:
    name: envoy.retry_priorities.previous_priorities
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.priority.previous_priorities.v3.PreviousPrioritiesConfig
      update_frequency: 2

这将针对尚未使用的后续重试尝试中的优先级。该update_frequency参数决定了重新计算优先级负载的频率。

  • 这些插件可以组合,这将排除以前尝试过的主机以及以前尝试过的优先级。
retry_policy:
  retry_host_predicate:
  - name: envoy.retry_host_predicates.previous_hosts
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
  host_selection_retry_max_attempts: 3
  retry_priority:
    name: envoy.retry_priorities.previous_priorities
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.retry.priority.previous_priorities.v3.PreviousPrioritiesConfig
      update_frequency: 2

标签:retry,name,envoy,局部,Envoy,重试,故障,address,type
From: https://www.cnblogs.com/wangguishe/p/16661984.html

相关文章

  • Envoy 流量镜像
    流量镜像流量镜像,也称为流量复制或影子镜像流量镜像功能通常用于在生产环境进行测试,通过将生产流量镜像拷贝到测试集群或者新版本集群,实现新版本接近真实环境的测试,旨......
  • KingbaseES 局部索引
    一个列要不要建立btree索引,判断条件是其键值分布是否够离散,比如主键、唯一键,可以建立索引。如果这个列有大量重复的值,则建立索引没有意义。在生产环境中常会碰到键值分布......
  • vue3 基础-全局组件和局部组件
    组件和页面的关系可以理解为,组件是页面的一部分.形象地理解组件就和盖房子一样的,可以将房子粗略拆分3个组件(组成部分)房顶,房身,地基.同时房顶又可以拆分...........
  • 8、实现故障和恢复的邮件通知
    8、实现故障和恢复的邮件通知环境:虚拟机实现联网(略)zabbix实现监控(略)zabbix-server实现smtp(略) 8.1:邮件通知:通过企业邮箱、第三方服务商邮箱发送报警邮件通知运维工......
  • 3.实现redis哨兵,模拟master故障场景
    3.实现redis哨兵,模拟master故障场景实验拓扑图  3.1哨兵的准备实现主从复制架构哨兵的前提是已经实现了一个redis的主从复制的运行环境,从而实现一个一主两从基于......
  • el-image局部显示(不全屏遮罩)
    需要修改遮罩层的定位,使用绝对定位,设置遮罩层的大小,注意样式修改需要是全局样式,不能用scoped<stylelang="scss">.el-image-viewer__wrapper{position:absolut......
  • Envoy 集群故障处理机制
    故障处理机制Envoy提供了一系列开箱即用的故障处理机制;超时(timeout)有限次数的重试,并支持可变的重试延迟主动健康检查与异常探测连接池断路器所有......
  • 【HDFS】一次Namenode的RPC延迟故障排查引发的深入思考
    一次Namenode的RPC延迟故障排查引发的深入思考前言正文问题排查初步定位临时恢复定位可疑进程问题分析问题脚本分析问题原因分析代码分析测试代码prometheus_clien......
  • 荧光光度计的七种故障解决方法
    我们在使用原子荧光光度计时有可能会遇到各种故障,那么本篇就为大家分享一些常见的故障及排除方法吧。 一、点火问题在分析工作中,经常会碰到部分仪器点火线圈不......
  • 成员变量和局部变量的区别和面向对象的三大特征之封装性
    成员变量和局部变量的区别1、定义的位置不一样【重点】局部变量:在方法的内部成员变量:在方法的外部,直接鞋子类当中2、作用范围不一样【重点】局部变量:只有方法当中才可......