Re: wait time при кешировании proxy cache

2018-02-22 Пенетрантность Maxim Dounin
Hello!

On Thu, Feb 22, 2018 at 12:03:10PM -0500, Bloof wrote:

> Добрый день.
> 
> Я использую nginx как раздающий сервер для кеширования небольших видеофайлов
> с другого сервера-хранилища. Среднее время получения одного файла из
> хранилища 20 мсек, максимальное 200 мсек. Если два клиента приходят к nginx
> за одним файлом практически одновременно, то nginx одного клиента ставит на
> загрузку файла из хранилища, а второй клиент попадает на ожидание
> lock_timeout/lock_age
> (https://github.com/nginx/nginx/blob/branches/stable-1.12/src/http/ngx_http_file_cache.c#L452).
> При этом ставится таймер, который каждые 500 мсек проверяет наличие файла в
> кеше. Получается, что время таймера сильно больше времени получения файла из
> хранилища. Уменьшать proxy_cache_lock_timeout нет возможности, так как можно
> перегрузить канал между nginx и хранилищем. Есть ли возможность
> обойти/уменьшить этот таймер, кроме как менять значение в сорцах и
> перекомпилировать nginx? Можно ли поставить что-то типа inotify ивента на
> появление/изменение файла в кеше?

Нет, сейчас способов как-то повлиять на этот таймер, кроме как с 
помощью малого значения proxy_cache_lock_timeout, нет.

-- 
Maxim Dounin
http://mdounin.ru/
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: sendfile() failed (9: Bad file descriptor) while sending request to upstream

2018-02-22 Пенетрантность Maxim Dounin
Hello!

On Thu, Feb 22, 2018 at 08:12:25AM -0500, papajoe wrote:

> Hey everybody,
> 
> I experienced this issue using nginx version 1.10.x and 1.13.x
> 
> 
> given a basic configuration like:
> 
> upstream myupstream {
> server internal01:80;
> server internal02:80 backup;
> }
> 
> server {
> listen 81 default_server;
> listen [::]:81 default_server;
> 
> server_name _;
> 
> location / {
> proxy_pass http://myupstream;
> post_action @hot_standby;
> }
> 
> location @hot_standby {
> proxy_pass http://internal02:80;
> }
> }
> 
> 
> I receive the "sendfile() failed (9: Bad file descriptor) while sending
> request to upstream"  error when trying to POST data exceeding 16k body
> size. The error does not occur for requests with less than 16k data.
> As far as I can understand the code / documentation, 16k by default (for
> 64bit systems) is the limit when nginx starts to use a tempfile instead of a
> memory buffer.
> http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
> 
> This makes me believe that the problem only kicks in when nginx decides to
> use a tempfile instead of an inmemory buffer.
> 
> 
> For my setup I was able to fix the issue by an alignment between
> client_body_buffer_size and client_max_body_size.
> 
> client_max_body_size1m;
> client_body_buffer_size   1m;
> 
> 
> Hope this can help anybody.

Just in case you are interested in details, this is a result in 
optimization in the proxy module, which removes the request body 
file as soon as a response is received.  Additional details can be 
found here:

http://hg.nginx.org/nginx/rev/f583559aadc7
https://trac.nginx.org/nginx/ticket/585

To fix this, consider using mirror instead of the [intentionally 
undocumented] post_action directive, see 
http://nginx.org/en/docs/http/ngx_http_mirror_module.html.

-- 
Maxim Dounin
http://mdounin.ru/
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

wait time при кешировании proxy cache

2018-02-22 Пенетрантность Bloof
Добрый день.

Я использую nginx как раздающий сервер для кеширования небольших видеофайлов
с другого сервера-хранилища. Среднее время получения одного файла из
хранилища 20 мсек, максимальное 200 мсек. Если два клиента приходят к nginx
за одним файлом практически одновременно, то nginx одного клиента ставит на
загрузку файла из хранилища, а второй клиент попадает на ожидание
lock_timeout/lock_age
(https://github.com/nginx/nginx/blob/branches/stable-1.12/src/http/ngx_http_file_cache.c#L452).
При этом ставится таймер, который каждые 500 мсек проверяет наличие файла в
кеше. Получается, что время таймера сильно больше времени получения файла из
хранилища. Уменьшать proxy_cache_lock_timeout нет возможности, так как можно
перегрузить канал между nginx и хранилищем. Есть ли возможность
обойти/уменьшить этот таймер, кроме как менять значение в сорцах и
перекомпилировать nginx? Можно ли поставить что-то типа inotify ивента на
появление/изменение файла в кеше?

Мой nginx.conf

worker_processes 8;
worker_cpu_affinity auto;

events {
worker_connections 32768;
use epoll;
multi_accept on;
}

http {
sendfile on;
tcp_nopush on;

proxy_cache_path /storage/cache levels=1:2 keys_zone=ssd_cache:10m
inactive=10m use_temp_path=off max_size=1G;
proxy_http_version 1.1;

upstream backend {
server some_other_server:80 max_fails=0;
keepalive 16;
}

server {
listen 80;

location ~ ^/($.+)\.mp4$ {
proxy_pass http://backend;
proxy_cache_key "$request_method|$fname";
proxy_cache ssd_cache;
proxy_cache_revalidate on;
proxy_set_header Connection "";
proxy_cache_lock on;
proxy_cache_lock_timeout 300s;
proxy_cache_lock_age 5s;
proxy_cache_use_stale error timeout invalid_header updating;
proxy_buffering on;
}
}
}

Posted at Nginx Forum: 
https://forum.nginx.org/read.php?21,278731,278731#msg-278731

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Igor Savenko
Спасибо! :) Понятно

22 февраля 2018 г., 18:52 пользователь Maxim Dounin 
написал:

> Hello!
>
> On Thu, Feb 22, 2018 at 06:15:35PM +0200, Igor Savenko wrote:
>
> > Большое спасибо, Максим! Тем временем, я обратил внимание на то, каким
> > образом в openresty реализован фукнционал сдвига выполнения модуля в
> самый
> > конец фазы:
> >
> > if (!lmcf->postponed_to_access_phase_end) {
> >
> > lmcf->postponed_to_access_phase_end = 1;
> >
> > cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
> >
> > ph = cmcf->phase_engine.handlers;
> > cur_ph = [r->phase_handler];
>
> [...]
>
> > Актуален ли данный подход? Это хак, недокументированная возможность или
> > широкоизвестная в узких кругах функциональность?
>
> Приблизительно всё, что можно найти в openresty - это хаки разной
> степени тяжести.  Процитированный код - характерный представитель.
>
> Во-первых, он лезет во внутренние структуры http core.  Однажды мы
> что-нибудь поменяем внутри - и оно всё сломается с удивительными
> спецэффектами.
>
> Во-вторых, он пытается менять конфигурацию внутри работающего
> рабочего процесса.  Это просто глупо, так как приведёт к тому, что
> соответствующие структуры будут дублироваться в памяти разных
> рабочих процессов.
>
> Не надо делать так.
>
> --
> Maxim Dounin
> http://mdounin.ru/
> ___
> nginx-ru mailing list
> nginx-ru@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
>
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Maxim Dounin
Hello!

On Thu, Feb 22, 2018 at 06:15:35PM +0200, Igor Savenko wrote:

> Большое спасибо, Максим! Тем временем, я обратил внимание на то, каким
> образом в openresty реализован фукнционал сдвига выполнения модуля в самый
> конец фазы:
> 
> if (!lmcf->postponed_to_access_phase_end) {
> 
> lmcf->postponed_to_access_phase_end = 1;
> 
> cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
> 
> ph = cmcf->phase_engine.handlers;
> cur_ph = [r->phase_handler];

[...]

> Актуален ли данный подход? Это хак, недокументированная возможность или
> широкоизвестная в узких кругах функциональность?

Приблизительно всё, что можно найти в openresty - это хаки разной
степени тяжести.  Процитированный код - характерный представитель.  

Во-первых, он лезет во внутренние структуры http core.  Однажды мы 
что-нибудь поменяем внутри - и оно всё сломается с удивительными 
спецэффектами.

Во-вторых, он пытается менять конфигурацию внутри работающего 
рабочего процесса.  Это просто глупо, так как приведёт к тому, что 
соответствующие структуры будут дублироваться в памяти разных 
рабочих процессов.

Не надо делать так.

-- 
Maxim Dounin
http://mdounin.ru/
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Igor Savenko
Большое спасибо, Максим! Тем временем, я обратил внимание на то, каким
образом в openresty реализован фукнционал сдвига выполнения модуля в самый
конец фазы:

if (!lmcf->postponed_to_access_phase_end) {

lmcf->postponed_to_access_phase_end = 1;

cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

ph = cmcf->phase_engine.handlers;
cur_ph = [r->phase_handler];

/* we should skip the post_access phase handler here too */
last_ph = [cur_ph->next - 2];

dd("ph cur: %d, ph next: %d", (int) r->phase_handler,
   (int) (cur_ph->next - 2));

#if 0
if (cur_ph == last_ph) {
dd("XXX our handler is already the last access phase handler");
}
#endif

if (cur_ph < last_ph) {
dd("swaping the contents of cur_ph and last_ph...");

tmp = *cur_ph;

memmove(cur_ph, cur_ph + 1,
(last_ph - cur_ph) * sizeof (ngx_http_phase_handler_t));

*last_ph = tmp;

r->phase_handler--; /* redo the current ph */

return NGX_DECLINED;
}
}

Актуален ли данный подход? Это хак, недокументированная возможность или
широкоизвестная в узких кругах функциональность?

22 февраля 2018 г., 18:08 пользователь Maxim Dounin 
написал:

> Hello!
>
> On Thu, Feb 22, 2018 at 03:10:04PM +0200, Igor Savenko wrote:
>
> > Добрый день! Есть ли способ указать, что данный хендлер (в моем случае
> > ModSecurity handler в access-phase) должен вызываться последним Или после
> > определенного хендлера? Или, как воркэраунд, в данном модуле проверить
> > определенное условие, и если оно не выставлено, выдать NGX_DECLINED,
> чтобы
> > потом этот модуль в акцесс-фазе был вызван вновь, после того, как
> остальные
> > хендлеры уже отработали?
>
> Порядок вызова модулей в фазе определяется при сборке - сначала
> вызываются обработчики тех модулей, которые идут в списке модулей
> последними (и соответственно добавили свой обработчик в фазу
> последними).  Соответственно в access-фазе сторонние модули в
> общем случае будут вызываться раньше встроенных, а взаимный
> порядок сторонних модулей определяется порядком опций --add-module.
>
> Чуть больше контроля есть при динамической загрузке - с помощью
> переменной ngx_module_order можно задать произвольную позицию,
> куда следует загружать модуль.
>
> Но вообще, если порядок вдруг важен - стоит подумать о том,
> правильно ли выбрана фаза.  Если хочется позвать обработчик
> последним - то, возможно, вам нужна другая фаза.
>
> > Влияет ли на этот фукнционал состояние директивы satisfy ?
>
> Директива satisfy определяет, будет ли требоватся разрешение на
> выполнение от всех модулей access-фазы (all) или хотя бы от одного
> (any).  В случае "satisfy all" все модули фазы вызываются
> последовательно, если хотя бы один из них вернёт ошибку -
> пользователю будет возвращена ошибка.  В случае "satisfy any" все
> модули фазы вызываются последовательно, пока хотя бы один из них
> не разрешит выполнение запроса.  После этого обработка запроса
> переходит к следующей фазе, остальные модули фазы не вызываются.
>
> Вышеописанное следует учитывать при создании модулей для
> access-фазы - в случае "satisfy any" они могут не быть вызваны
> вовсе (если какой-то другой модуль разрешил выполнение запроса), и
> сами не должны возвращать NGX_OK, если не хотят явно разрешить
> доступ клиенту, минуя проверки других модулей.
>
> --
> Maxim Dounin
> http://mdounin.ru/
> ___
> nginx-ru mailing list
> nginx-ru@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Maxim Dounin
Hello!

On Thu, Feb 22, 2018 at 03:10:04PM +0200, Igor Savenko wrote:

> Добрый день! Есть ли способ указать, что данный хендлер (в моем случае
> ModSecurity handler в access-phase) должен вызываться последним Или после
> определенного хендлера? Или, как воркэраунд, в данном модуле проверить
> определенное условие, и если оно не выставлено, выдать NGX_DECLINED, чтобы
> потом этот модуль в акцесс-фазе был вызван вновь, после того, как остальные
> хендлеры уже отработали?

Порядок вызова модулей в фазе определяется при сборке - сначала 
вызываются обработчики тех модулей, которые идут в списке модулей 
последними (и соответственно добавили свой обработчик в фазу 
последними).  Соответственно в access-фазе сторонние модули в 
общем случае будут вызываться раньше встроенных, а взаимный 
порядок сторонних модулей определяется порядком опций --add-module.

Чуть больше контроля есть при динамической загрузке - с помощью 
переменной ngx_module_order можно задать произвольную позицию, 
куда следует загружать модуль.

Но вообще, если порядок вдруг важен - стоит подумать о том, 
правильно ли выбрана фаза.  Если хочется позвать обработчик 
последним - то, возможно, вам нужна другая фаза.

> Влияет ли на этот фукнционал состояние директивы satisfy ?

Директива satisfy определяет, будет ли требоватся разрешение на 
выполнение от всех модулей access-фазы (all) или хотя бы от одного 
(any).  В случае "satisfy all" все модули фазы вызываются 
последовательно, если хотя бы один из них вернёт ошибку - 
пользователю будет возвращена ошибка.  В случае "satisfy any" все 
модули фазы вызываются последовательно, пока хотя бы один из них 
не разрешит выполнение запроса.  После этого обработка запроса 
переходит к следующей фазе, остальные модули фазы не вызываются.

Вышеописанное следует учитывать при создании модулей для 
access-фазы - в случае "satisfy any" они могут не быть вызваны 
вовсе (если какой-то другой модуль разрешил выполнение запроса), и 
сами не должны возвращать NGX_OK, если не хотят явно разрешить 
доступ клиенту, минуя проверки других модулей.

-- 
Maxim Dounin
http://mdounin.ru/
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: sendfile() failed (9: Bad file descriptor) while sending request to upstream

2018-02-22 Пенетрантность papajoe
Hey everybody,

I experienced this issue using nginx version 1.10.x and 1.13.x


given a basic configuration like:

upstream myupstream {
server internal01:80;
server internal02:80 backup;
}

server {
listen 81 default_server;
listen [::]:81 default_server;

server_name _;

location / {
proxy_pass http://myupstream;
post_action @hot_standby;
}

location @hot_standby {
proxy_pass http://internal02:80;
}
}


I receive the "sendfile() failed (9: Bad file descriptor) while sending
request to upstream"  error when trying to POST data exceeding 16k body
size. The error does not occur for requests with less than 16k data.
As far as I can understand the code / documentation, 16k by default (for
64bit systems) is the limit when nginx starts to use a tempfile instead of a
memory buffer.
http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size

This makes me believe that the problem only kicks in when nginx decides to
use a tempfile instead of an inmemory buffer.


For my setup I was able to fix the issue by an alignment between
client_body_buffer_size and client_max_body_size.

client_max_body_size1m;
client_body_buffer_size   1m;


Hope this can help anybody.

Best
Benny

Posted at Nginx Forum: 
https://forum.nginx.org/read.php?21,118976,278721#msg-278721

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Igor Savenko
Добрый день! Есть ли способ указать, что данный хендлер (в моем случае
ModSecurity handler в access-phase) должен вызываться последним Или после
определенного хендлера? Или, как воркэраунд, в данном модуле проверить
определенное условие, и если оно не выставлено, выдать NGX_DECLINED, чтобы
потом этот модуль в акцесс-фазе был вызван вновь, после того, как остальные
хендлеры уже отработали? Влияет ли на этот фукнционал состояние директивы
satisfy ?
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru