Разрыв цепи посланника без детерминированности c Поведение - PullRequest
0 голосов
/ 11 февраля 2020

Наши эксперименты с разрывом цепи посланника показали, что результаты не были детерминированными c. Это было продемонстрировано нашими попытками преднамеренного отключения цепей с использованием такой установки:

enter image description here

Сервис представляет собой простой веб-сервер, который возвращает 200 с задержкой в ​​2 секунды (задержка гарантирует, что сервер остается занятым между асинхронными запросами). Снимок конфигурации дополнительной машины нашего посланника показывает, что мы включаем разрыв цепи (через http / 1.1) с максимум 1 соединением и 1 ожидающим запросом:

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

Далее мы проверили это, отправив отдельные запросы. на сервис, на который он надежно отвечает 200, как и ожидалось.

Однако, если мы теперь отправим 2 асинхронных запроса в службу, мы увидим неожиданные результаты. Иногда он возвращает 200 для обоих запросов, которые он не должен выполнять, поскольку второй запрос должен отключить автоматический выключатель. В других случаях один запрос возвращает 200, а другой возвращает 503 Service Unavailable, что мы и ожидаем. Несмотря на все наши усилия, мы не смогли добиться какой-либо повторяемости, что привело нас к мысли, что это связано с основным параллелизмом посланника.

Когда мы изменили max_connections и max_pending_requests на более крупные числа (> 100 ) и снова отправил слишком много запросов в попытке отключить схему, мы обнаружили, что это несоответствие осталось. Количество разрешенных запросов было приблизительно правильным, но иногда отклонялось несколькими.

Мы надеемся понять причины отсутствия абсолютного детерминизма. Любая помощь высоко ценится! См. репо для кода

РЕДАКТИРОВАТЬ: Существует проблема , описывающая подобное неожиданное поведение, но я не ближе к поиску Soln.

Я включил журналы двух запросов, чтобы продемонстрировать вывод:

  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
Отправка 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

1 Ответ

0 голосов
/ 04 марта 2020

От одного из участников на здесь :

Автоматические выключатели предназначены для предотвращения распространения слишком большой нагрузки через систему, а не для строгого ограничения. Система реализована таким образом, что является более простой и производительной, но в некоторых случаях может немного превышать ограничения. Здесь комментарий от реализации отслеживания предела автоматического выключателя

...