@catquistador

Почему некорректно считается req_limit?

в блоке http {} прописан limit_req_zone $binary_remote_addr zone=test:30m rate=1000r/s;
в server { location {}} прописан limit_req zone=test burst=10 nodelay;
Тест запускаю ApacheBenchmark'ом ab -n 10000 -c 80 http://localhost:80/test

Concurrency Level: 80
Time taken for tests: 9.743 seconds
Complete requests: 10000
Failed requests: 6289
(Connect: 0, Receive: 0, Length: 6289, Exceptions: 0)
Non-2xx responses: 6289
Total transferred: 3104023 bytes
HTML transferred: 1490115 bytes
Requests per second: 1026.34 [#/sec] (mean)
Time per request: 77.947 [ms] (mean)
Time per request: 0.974 [ms] (mean, across all concurrent requests)
Transfer rate: 311.11 [Kbytes/sec] received


на выход получаю 62% провалившихся запросов. при том, что RPS едва перехватил за лимит
более того, в ряде случаев при RPS ниже лимита утекают коннекты.
В логах спам
56360 limiting requests, excess: 11.000 by zone "test", client: 127.0.0.1, server: test, request: "GET /test HTTP/1.0", host: "localhost"

не понимаю, откуда такие потери и почему в логе "excess 11.000". в моём понимании там должно быть ~1010 (rps limit + burst)
  • Вопрос задан
  • 109 просмотров
Решения вопроса 1
ky0
@ky0 Куратор тега Nginx
Миллиардер, филантроп, патологический лгун
Давайте разберём самое начало процесса, когда запускается ab и в нгинкс примерно одновременно начинают лететь 80 запросов. Счётчики в этот момент по нулям, но выставлен лимит в 1000 rps, то есть запросы могут обрабатываться не чаще, чем раз в 1 мсек.

По факту, внутрь провалятся ровно 1+10=11 запросов, а остальные 80-11=69 отобьются с 503 кодом - это даже больше 62%.

В дальнейшем, поскольку запросы постепенно размажутся во времени, перестав приходить синхронно, процент отлупов снизится, но отнюдь не до ожидаемых вами (1026-1000)/1000*100%, потому что время от времени (и скорее часто, чем редко) запросы всё-таки будут приходить чаще, чем раз в 1 мсек (бурст в 10 rps можно не учитывать, он по сравнению с лимитом микроскопический) - на это намекает среднее время исполнения 0.974 мсек, делёное на 80 потоков.

Попробуйте увеличить бурст, скажем, до 500-1000 и посмотреть, как это отразится на результатах.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы