【问题标题】:Envoy Circuit Breaking Non Deterministic BehaviourEnvoy 断路非确定性行为
【发布时间】:2020-05-26 12:10:09
【问题描述】:

我们对 envoy 的 circuit breaking 的实验表明结果不是确定性的。我们尝试使用这样的设置故意跳闸电路证明了这一点:

该服务是一个简单的 Web 服务器,它返回一个带有 2 秒时间延迟的 200(时间延迟确保服务器在异步请求之间保持忙碌)。我们的 envoy sidecar 配置快照显示我们启用了熔断(通过 http/1.1),最多有 1 个连接和 1 个待处理请求:

circuit_breakers:
   thresholds:
     - priority: "DEFAULT"
       max_connections: 1
       max_pending_requests: 1

接下来,我们通过向服务发送单个请求来测试此方法是否有效,它会按预期以200 可靠地响应该请求。

但是,如果我们现在向服务发送 2 个异步请求,我们会看到意想不到的结果。它有时会为两个请求返回200,因为第二个请求应该使断路器跳闸,所以它不应该这样做。在其他情况下,一个请求返回一个200,另一个返回一个503 Service Unavailable,这是我们期望发生的。尽管我们尽了最大努力,但我们无法实现任何形式的可重复性,这导致我们认为这与 envoy 的底层并发性有关。

当我们将 max_connectionsmax_pending_requests 更改为更大的数字 (>100) 并再次发送太多请求以尝试使电路跳闸时,我们发现这种不一致仍然存在。允许的请求数大致正确,但有时会相差几个。

我们希望了解这种缺乏绝对确定性的原因。任何帮助深表感谢!代码见repo

编辑:有一个issue 详细说明了类似的意外行为,但我离找到解决方案还差得远。

我已经包含了两个请求的日志来演示输出:

  1. 同时发送 3 个请求,其中 1 个通过。
❯ (printf '%s\n' {1..3}) | xargs -I % -P 20 curl -v "http://localhost:3000?status=200&sleep=2"
**    Trying ::1...
  Trying ::1...
**  TCP_NODELAY set
TCP_NODELAY set
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3000 (#0)
* Connected to localhost (::1) port 3000 (#0)
> GET /?status=200&sleep=2 HTTP/1.1
>>  GET /?status=200&sleep=2 HTTP/1.1
Host: localhost:3000
>>  Host: localhost:3000
User-Agent: curl/7.64.1
>>  User-Agent: curl/7.64.1
Accept: */*
>>  Accept: */*

>
* Connected to localhost (::1) port 3000 (#0)
> GET /?status=200&sleep=2 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 503 Service Unavailable
< content-length: 81
< content-type: text/plain
< x-envoy-overloaded: true
< date: Wed, 12 Feb 2020 03:36:29 GMT
< server: envoy
<
* Connection #0 to host localhost left intact
upstream connect error or disconnect/reset before headers. reset reason: overflow* Closing connection 0
< HTTP/1.1 503 Service Unavailable
< content-length: 81
< content-type: text/plain
< x-envoy-overloaded: true
< date: Wed, 12 Feb 2020 03:36:29 GMT
< server: envoy
<
* Connection #0 to host localhost left intact
upstream connect error or disconnect/reset before headers. reset reason: overflow* Closing connection 0
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 3
< server: envoy
< date: Wed, 12 Feb 2020 03:36:31 GMT
< x-envoy-upstream-service-time: 2007
<
* Connection #0 to host localhost left intact
200* Closing connection 0
  1. 同时发送3个请求,全部返回200。
❯ (printf '%s\n' {1..3}) | xargs -I % -P 20 curl -v "http://localhost:3000?status=200&sleep=2"
**    Trying ::1...
  Trying ::1...
**  TCP_NODELAY set
TCP_NODELAY set
* *  Trying ::1...
 *Connected to localhost (::1) port 3000 (#0)
*  TCP_NODELAY set
Connected to localhost (::1) port 3000 (#0)
> GET /?status=200&sleep=2 HTTP/1.1
> >Host: localhost:3000
 >GET /?status=200&sleep=2 HTTP/1.1
 User-Agent: curl/7.64.1
>>  Accept: */*
Host: localhost:3000
> >
 User-Agent: curl/7.64.1
> Accept: */*
>
* Connected to localhost (::1) port 3000 (#0)
> GET /?status=200&sleep=2 HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 3
< server: envoy
< date: Wed, 12 Feb 2020 03:40:50 GMT
< x-envoy-upstream-service-time: 2006
<
* Connection #0 to host localhost left intact
200* Closing connection 0
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 3
< server: envoy
< date: Wed, 12 Feb 2020 03:40:52 GMT
< x-envoy-upstream-service-time: 4011
<
* Connection #0 to host localhost left intact
200* Closing connection 0
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 3
< server: envoy
< date: Wed, 12 Feb 2020 03:40:54 GMT
< x-envoy-upstream-service-time: 6015
<
* Connection #0 to host localhost left intact
200* Closing connection 0

【问题讨论】:

  • 您确定您的 HTTP 会话是每个连接一个请求而不是保持活动状态吗?
  • 可能会发布完整的流量捕获/包含所有标头和时间戳。
  • @BadZen 由于输出显示“关闭连接”,我认为这意味着它没有保持活动状态?请查看更新的编辑
  • @rohaldb,据我了解,断路器适用于从代理发送到上游服务器的连接;不要传入到代理的连接。所以代理仍然可以接受请求,如果路由和客户端的超时都没有过期,那么请求仍然可以通过。如果你只睡了 2 秒,但路由超时是 15 秒(我认为这是默认设置),那么可能会出现这种不一致的行为。可能值得卷曲 /stats 端点并观察活动请求;看看它是否超过你的价值。

标签: networking concurrency envoyproxy circuit-breaker


【解决方案1】:

来自here 上的一位贡献者:

断路器旨在防止过多的负载通过系统传播,而不是强制执行严格的限制。该系统以更简单、性能更高的方式实现,但在某些情况下可能会略微超出限制。 Here的评论来自断路器限制跟踪的实现

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2021-01-07
    • 2016-03-12
    • 1970-01-01
    相关资源
    最近更新 更多