limit conn счетчик переполнение
Добрый день. Была задача ограничить кол-во запросов к бэкенду. Например, чтобы одновременно не поступало более 1 запроса. Остальные запросы, пока работает бэкенд, могли отваливаться по ошибке, это не страшно. С помощью Perl я устанавливал переменную, которая показывала идет ли запрос для проксирования на бэкенд или нет. И эту переменную использовал в качестве ключа для http://nginx.org/ru/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone perl_set $service_hit ' sub { my $r = shift; if($r-uri =~ m|^/services/post|){ return services; } else { return ; } } '; limit_conn_zone $service_hit zone=perservice:10m; Потом перед проксированием на бэкенд (в location) использовал ограничениие http://nginx.org/ru/docs/http/ngx_http_limit_conn_module.html#limit_conn limit_conn perservice 1; Все отлично работает, но только первые 30-60 минут, потом nginx для всех запросов возвращает 503 ошибку, т.е. счетчик не сбрасывается. Если остановить-запустить nginx, то опять какое-то время все работает корректно. В чем может быть проблема? Спасибо. Posted at Nginx Forum: http://forum.nginx.org/read.php?21,258140,258140#msg-258140 ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: limit conn счетчик переполнение
Hello! On Fri, Apr 17, 2015 at 06:06:49AM -0400, dwow wrote: Добрый день. Была задача ограничить кол-во запросов к бэкенду. Например, чтобы одновременно не поступало более 1 запроса. Остальные запросы, пока работает бэкенд, могли отваливаться по ошибке, это не страшно. С помощью Perl я устанавливал переменную, которая показывала идет ли запрос для проксирования на бэкенд или нет. И эту переменную использовал в качестве ключа для http://nginx.org/ru/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone perl_set $service_hit ' sub { my $r = shift; if($r-uri =~ m|^/services/post|){ return services; } else { return ; } } '; limit_conn_zone $service_hit zone=perservice:10m; Just a side note: не надо делать так, вместо этого правильно написать отдельный location, в котором и задать ограничение. Потом перед проксированием на бэкенд (в location) использовал ограничениие http://nginx.org/ru/docs/http/ngx_http_limit_conn_module.html#limit_conn limit_conn perservice 1; Все отлично работает, но только первые 30-60 минут, потом nginx для всех запросов возвращает 503 ошибку, т.е. счетчик не сбрасывается. Если остановить-запустить nginx, то опять какое-то время все работает корректно. В чем может быть проблема? Скорее всего проблема в том, что limit_conn органичивает не соединения на бекенду, а активные соединения. Соответственно, если кто-то сходил на бекенд, получил оттуда достаточно большой ответ и неспеша забирает его у nginx'а - ограничение будет продолжать срабатывать. Например, если клиент сделал запрос (ответ на который не помещается в буфер сокета), после чего пропал и на пакеты не отвечает - ограничение будет срабатывать, пока не случится send_timeout. -- Maxim Dounin http://nginx.org/ ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: limit conn счетчик переполнение
Hello! On Fri, Apr 17, 2015 at 09:15:21AM -0400, dwow wrote: Maxim Dounin Wrote: --- Just a side note: не надо делать так, вместо этого правильно написать отдельный location, в котором и задать ограничение. вот это я не понял. у меня так location /services/post/ { limit_conn perservice 1; proxy_pass bakcend; } Тогда зачем у вас используется perl_set? Если limit_conn в других location'ах не включён, то для ограничения всех соединений в конкретном location'е - достаточно любого константного значения. Скорее всего проблема в том, что limit_conn органичивает не соединения на бекенду, а активные соединения. Соответственно, если кто-то сходил на бекенд, получил оттуда достаточно большой ответ и неспеша забирает его у nginx'а - ограничение будет продолжать срабатывать. Например, если клиент сделал запрос (ответ на который не помещается в буфер сокета), после чего пропал и на пакеты не отвечает - ограничение будет срабатывать, пока не случится send_timeout. Ага, и тогда через send_timeout (default: 60s), счетчик должен декрементироваться и следующий запрос пойти на бекенд, так? Но этого не происходит( Если send_timeout случится - то да. Если же вдруг какой-то клиент очерь медленно качает что-то большое - то процесс может занять бесконечное время. Ну и да, безусловно имеет смысл заглянуть в error log, и убедится, что рабочие процессы не завершаются аварийно. -- Maxim Dounin http://nginx.org/ ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: limit conn счетчик переполнение
On 17.04.2015 19:28, dwow wrote: Была задача ограничить кол-во запросов к бэкенду. Например, чтобы одновременно не поступало более 1 запроса. Если же вдруг какой-то клиент очерь медленно качает что-то большое - то процесс может занять бесконечное время. и как от таких избавляться? 1) купить платную версию NGINX Plus, там есть max_conns=number http://nginx.org/en/docs/http/ngx_http_upstream_module.html 2) поставить между клиентом [или nginx] и бэкендом haproxy - haproxy умеет это делать прямо из коробки: https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#5.2-maxconn -- Best regards, Gena ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru
Re: limit conn счетчик переполнение
Hello! On Fri, Apr 17, 2015 at 12:28:03PM -0400, dwow wrote: Maxim Dounin Wrote: --- Если limit_conn в других location'ах не включён, то для ограничения всех соединений в конкретном location'е - достаточно любого константного значения. Если не используется в др. локейшенах, то можно сделать вот так: limit_conn_zone service zone=perservice:10m; location /services/post/ { limit_conn perservice 1; proxy_pass bakcend; } и будет работать? Да. В старых версиях (до nginx 1.7.6), возможно, потребуется какая-нибудь константная переменная (например, $nginx_version), а не просто строка. Если send_timeout случится - то да. Если же вдруг какой-то клиент очерь медленно качает что-то большое - то процесс может занять бесконечное время. и как от таких избавляться? В общем случае - никак, это обычные клиенты, которые просто получают ответ. Собственно, как раз одно из преимуществ nginx'а состоит в том, что он умеет таких клиентов эффективно обслуживать, тратя на это минимум ресурсов. Ну и ограничивать с помощью директивы limit_conn, не давая захватить слишком много ресурсов сервера. В вашем случае - проблема в том, что вы пытаетесь limit_conn применить не по назначению, и такое использование приводит к тому, что один медленный пользователь может легко заблокировать доступ всем остальным. -- Maxim Dounin http://nginx.org/ ___ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru