Networking 断路器的非确定性行为

Networking 断路器的非确定性行为,networking,concurrency,envoyproxy,circuit-breaker,Networking,Concurrency,Envoyproxy,Circuit Breaker,我们与特使的实验表明,结果是不确定的。我们尝试使用如下设置故意跳闸电路,证明了这一点: 该服务是一个简单的web服务器,它返回一个200,延时2秒(延时确保服务器在异步请求之间保持忙碌)。我们的特使侧车配置的快照显示,我们启用断路(通过http/1.1),最多1个连接和1个挂起的请求: circuit_breakers: thresholds: - priority: "DEFAULT" max_connections: 1 max_pending_

我们与特使的实验表明,结果是不确定的。我们尝试使用如下设置故意跳闸电路,证明了这一点:

该服务是一个简单的web服务器,它返回一个
200
,延时2秒(延时确保服务器在异步请求之间保持忙碌)。我们的特使侧车配置的快照显示,我们启用断路(通过http/1.1),最多1个连接和1个挂起的请求:

circuit_breakers:
   thresholds:
     - priority: "DEFAULT"
       max_connections: 1
       max_pending_requests: 1
接下来,我们通过向服务发送单个请求来测试这一点,服务按照预期可靠地响应
200

但是,如果我们现在向服务发送两个异步请求,就会看到意外的结果。它有时会为两个请求返回
200
,因为第二个请求会使断路器跳闸,所以它不应该返回这两个请求。在其他情况下,一个请求返回一个
200
,另一个请求返回一个
503服务不可用
,这正是我们所期望的情况。尽管我们尽了最大努力,但我们无法实现任何重复性,这使我们认为这与特使潜在的一致性有关

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

我们希望理解这种缺乏绝对决定论的原因。非常感谢您的帮助!有关代码,请参阅

编辑:有一个细节类似的意外行为,但我不接近找到一个解决方案

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

  • 同时发送3个请求,1个通过
  • ❯ (printf'%s\n'{1..3})| xargs-I%-p20 curl-v”http://localhost:3000?status=200&sleep=2"
    **正在尝试::1。。。
    正在尝试::1。。。
    **TCP_节点集
    TCP_节点集
    *正在尝试::1。。。
    *TCP_节点集
    *已连接到本地主机(::1)端口3000(#0)
    *已连接到本地主机(::1)端口3000(#0)
    >获取/?status=200&sleep=2 HTTP/1.1
    >>获取/?status=200&sleep=2 HTTP/1.1
    主机:localhost:3000
    >>主机:localhost:3000
    用户代理:curl/7.64.1
    >>用户代理:curl/7.64.1
    接受:*/*
    >>接受:*/*
    >
    *已连接到本地主机(::1)端口3000(#0)
    >获取/?status=200&sleep=2 HTTP/1.1
    >主机:localhost:3000
    >用户代理:curl/7.64.1
    >接受:*/*
    >
    
  • 同时发送3个请求,所有请求返回200
    ❯ (printf'%s\n'{1..3})| xargs-I%-p20 curl-v”http://localhost:3000?status=200&sleep=2"
    **正在尝试::1。。。
    正在尝试::1。。。
    **TCP_节点集
    TCP_节点集
    **正在尝试::1。。。
    *已连接到本地主机(::1)端口3000(#0)
    *TCP_节点集
    已连接到本地主机(::1)端口3000(#0)
    >获取/?status=200&sleep=2 HTTP/1.1
    >>主机:本地主机:3000
    >获取/?status=200&sleep=2 HTTP/1.1
    用户代理:curl/7.64.1
    >>接受:*/*
    主机:localhost:3000
    > >
    用户代理:curl/7.64.1
    >接受:*/*
    >
    *已连接到本地主机(::1)端口3000(#0)
    >获取/?status=200&sleep=2 HTTP/1.1
    >主机:localhost:3000
    >用户代理:curl/7.64.1
    >接受:*/*
    >
    
    来自以下网站上的某个贡献者:

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


    您确定您的HTTP会话是每个连接一个请求而不保持活动状态吗?可能会发布一个完整的流量捕获/w所有头和时间戳。@BadZen由于输出显示“关闭连接”,我认为这意味着它不保持活动状态?请参阅更新的edits@rohaldb,据我所知,断路器适用于从代理发送到上游服务器的连接;不连接到代理的传入连接。因此,代理仍然可以接受请求,如果路由和客户端的超时都没有过期,那么请求仍然可以通过。如果你只睡了2秒钟,但是路由超时是15秒(我想这是d
    ❯ (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
    
    ❯ (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