重试超时策略:请求失败重试的设置

最大请求次数:可重试的最大次数

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

    单次重试有其操作时长

    所有的重试都包含在请求超时时长之类,多次重试的时长总和不能超过设定的超时时长

retry_policy: {...}
  "retry_on": "..." # 重试发生的条件, 其功能同x-envoy-retry-on和x-envoy-retry-grpc-on标头相同;
  "num_retries": "{...}" # 重试次数, 默认值为1, 其功能同x-envoy-max-retries标头相同,但采用二者中配置的最大值;
  "per_try_timeout": "{...}" # 单次超时时长;
  "retry_priority": "{...}" # 配置重试优先级策略,用于在各优先级之间分配负载;
  "retry_host_predicate": [] # 重试时使用的主机断言(predicate)列表,各断言用于拒绝主机;于是,在选择重试主机时将参考该列表中的各断言,若存在任何谓词拒绝了一个主机,则需要重新尝试选择其它主机
  "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倍;
  "retriable_headers": [] # 触发重试的HTTP响应标头列表,上游端点的响应报文与列表中的任何标头匹配时将触发重试;
  "retriable_request_headers": [] # 必须在用于重试的请求报文中使用的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将尝试重试;

重试条件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:
  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.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/service/blue"
                route:
                  cluster: blue_abort
                  retry_policy:
                    retry_on: "5xx" # 重试条件
                    num_retries: 3 # 重试次数
              - match:
                  prefix: "/service/red"
                route:
                  cluster: red_delay
                  timeout: 1s # 超时时间
              - match:
                  prefix: "/service/green"
                route:
                  cluster: green
              - match:
                  prefix: "/"
                route:
                  cluster: mycluster
          http_filters:
          - name: envoy.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

重试插件:

        重试操作会触发重新选择目标主机。重试时选择主机会与首次相同,重试插件提供重试时选择的主机的方式,有以下两种方式。

Host Predicates:

        envoy.retry_host_predicates.previous_hosts:拒绝尝试过的主机

        envoy.retry_host_predicates.omit_canary_hosts:拒绝元数据中有Canary(金丝雀发布)的主机
Priority Predicates:

        envoy.retry_priority.previous_priorities:如果之前的优先级失败则调低优先级

retry_policy:
  retry_host_predicate:
  - name: envoy.retry_host_predicates.previous_hosts
  host_selection_retry_max_attempts: 3 # 重新选择主机的最大次数
  retry_priority:
    name: envoy.retry_priorities.previous_priorities
    config:
      update_frequency: 2 # 调整权重的更新频率

CORS跨域:

cors:
  "allow_origin": [] # 允许共享的资源列表, *表示所有;
  "allow_origin_regex": [] # 正则表达式模式表示的允许共享的资源
  "allow_methods": "..." # 允许资源访问时使用的HTTP方法列表, 内容将被序列化到access-control-allow-methods标头;
  "allow_headers": "..." # 允许在请求资源时使用HTTP标头列表, 内容将被序列化到access-control-allow-headers标头;
  "expose_headers": "..." # 浏览器可访问的HTTP标头白名单, 内容将被序列化到access-control-expose-headers标头;
  "max_age": "..." # 请求的缓存时长, 内容将被序列化到access-control-max-age标头;
  "allow_credentials": "{...}" # 布尔型值, 是否允许服务调用方法使用凭据发起实际请求;
  "enabled": "{...}" # 布尔型值, 是否启用CORS, 默认为启用; 此参数即将启用, 并由filter_enabled取代;
  "filter_enabled": "{...}" # 是否启用CORS过滤器, 若启用, 此处需要定义启用此过滤器的请求百分比, 默认为100/HUNDRED;
  default_value:
  numerator: ...
  denominator: ...
  runtime_key: ...
  "shadow_enabled": "{...}" # 是否仅在阴影模式下启用过滤器的请求的百分比, 若启用, 其默认值为100/HUNDRED; 若启用, 它将评估请求的来源以
  # 确定其是否有效, 但不强制执行任何策略; 若同时启用了filter_enabled和shadow_enabled, 则filter_enabled标志优先

CORS示例:

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
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
            - name: envoy.file_access_log
              typed_config:
                "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog
                path: "/var/log/access.log"
          route_config:
            name: local_route
            virtual_hosts:
            - name: www
              domains:
              - "*"
              cors:
                allow_origin: # 允许所有域名GET方法的跨域请求
                - "*"
                allow_methods: "GET"
                filter_enabled:
                  default_value:
                    numerator: 100
                    denominator: HUNDRED
                  runtime_key: cors.www.enabled
                shadow_enabled:
                  default_value:
                    numerator: 0
                    denominator: HUNDRED
                  runtime_key: cors.www.shadow_enabled
              routes:
              - match:
                  prefix: "/cors/open"
                route:
                  cluster: backend_service
              - match:
                  prefix: "/cors/disabled"
                route:
                  cluster: backend_service
                  cors:
                    filter_enabled:
                      default_value:
                        numerator: 0
                        denominator: HUNDRED
              - match:
                  prefix: "/cors/restricted"
                route:
                  cluster: backend_service
                  cors:
                    allow_origin: # 只允许这个域名的GET方法跨域请求
                    - "envoyproxy.io"
                    allow_methods: "GET"
              - match:
                  prefix: "/"
                route:
                  cluster: backend_service
          http_filters:
          - name: envoy.cors
            typed_config: {}
          - name: envoy.router
            typed_config: {}

  clusters:
  - name: backend_service
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    http2_protocol_options: {}
    load_assignment:
      cluster_name: backend_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: backendservice
                port_value: 80