Envoy HTTP流量管理 重试 超时 CORS跨域
重试超时策略:请求失败重试的设置
最大请求次数:可重试的最大次数
在每次重试之间使用指数指数退避算法
单次重试有其操作时长
所有的重试都包含在请求超时时长之类,多次重试的时长总和不能超过设定的超时时长
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