Вечный UPDATING для рандомных страниц портала
Alexey Galygin
mif на me.com
Пт Май 31 10:47:20 UTC 2019
всем привет
ПРОБЛЕМА
давно (уже не первый год обновление за обновлением nginx и OpenSSL) наблюдаем,
что ряд страниц при обновлении кэша входят в вечный статус UPDATING
см. curl вызовы ниже (ждали, что проблема уйдёт с обновлениями, но нет)
происходит это совершенно на рандомных страницах, и способа воспроизвести нет – только по прецедентной жалобе от пользователей, что закешированный контент не обновляется пол дня (ночью у нас рестарт nginx, который приводи всё в норму, но ждать до утра никто не хочет)
КОНФИГУРАЦИЯ
релевантные настройки такие:
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_lock_timeout 25s;
недавно поставили последнюю стабильную версию nginx + OpenSSL (сборка кастомная):
nginx version: nginx/1.16.0 built with OpenSSL 1.1.1b 26 Feb 2019 TLS SNI support enabled
при этом:
nginx -s reload # не помогает…
а помогает только явный «мягкий» перезапуск сервера (процедура похожая на обновление бинарника):
#!/usr/bin/env bash
# скрипт перезапуска или обновления бинарника:
sudo kill -s USR2 `cat /run/nginx.pid`
sudo kill -s WINCH `cat /run/nginx.pid.oldbin`
echo 'waiting for 5 minutes required for graceful reload'
sleep 300
sudo kill -s TERM `cat /run/nginx.pid.oldbin`
ЛОГИ И ДЕМО
есть предположение, что это из-за эпозодического падения worker'ов (таких набирается несколько десятков за день, при сотнях тысяч запросов)
dmesg:
[4505268.063116] nginx[22951]: segfault at 48 ip 00007f501a38682e sp 00007fff830e1470 error 4 in nginx.so[7f501a384000+5000]
…
error.log:
2019/05/31 10:35:23 [alert] 15685#15685: worker process 27862 exited on signal 11 (core dumped)
…
подобные падения нас пресделуют много лет (их в день не много), на самых разных версиях nginx, в разных ДЦ, на разных серверах, при разных окружениях;
(по хорошему, надо включить сбор корок и попытаться разобраться, где оно падает…)
наше предположение такое:
воркер, который должен был обновить истёкшие данные умирает, а статус так и остаётся UPDATING (на вечно),
всём клиентам отдаётся старый контент,
а новые воркеры уже не планируют запрос обновления с бэка
вот свежий пример (в заголовке x-ireland-cache-status выводим значение $upstream_cache_status):
H27: ~ $ curl -I https://www.hse.ru/our/
HTTP/2 200
server: nginx
date: Thu, 30 May 2019 14:54:52 GMT
…
x-ireland-cache-status: UPDATING
… можно очень долго ждать – статус так и будет UPDATING …
H27: ~ $ curl -I https://www.hse.ru/our/
HTTP/2 200
server: nginx
date: Thu, 30 May 2019 14:56:47 GMT
…
x-ireland-cache-status: UPDATING
после перезапуска nginx по SIGUSR2 скриптом (код перезапускатора был приведён выше):
H27: ~ $ curl -I https://www.hse.ru/our/
HTTP/2 200
server: nginx
date: Thu, 30 May 2019 14:57:37 GMT
…
x-ireland-cache-status: STALE
H27: ~ $ curl -I https://www.hse.ru/our/
HTTP/2 200
server: nginx
date: Thu, 30 May 2019 14:57:39 GMT
…
x-ireland-cache-status: HIT
всё, кэш успешно обновлён после перезапуска nginx! мы победили и ждём следующего звоночка…
у нас нет инструмента по отслеживанию «застрявших UPDATING»,
и нет способа точечно их пнуть
(если только не отслеживать $upstream_cache_status по каждому ресурсу и переходы статусов со временем, которые в 99.99% переходят из UPDATING в правильные статусы);
приходится ждать только сигнала от недовольных пользователей…
РЕЗЮМИРУЕМ
ещё раз, сценарий, как мы видим откуда растёт проблема:
1. некоторая страница успешно кэшируется
2. в какой-то момент идёт запрос на её обновление, но исполняющий воркер падает по SIGSEGV (таких падений несколько десятков за день из сотен тысяч запросов)
3. никакой больше воркер это задание не получает до перезапуска nginx
4. недовольные клиенты получают устаревший контент
РЕШЕНИЕ?
перезапускать nginx раз в 30 минут по cron для её решения не хотелось бы.
какие варианты решения подобной проблемы существуют? в чём может быть возможная причина?
может есть рекомендации по дополнительным настройкам?
да, падения могут быть обусловлены нашим кодом, или кастомной сборкой, но их (падения воркеров) надо учитывать в работе nginx:
если это рассматривать как баг nginx – можно ли найти ему решение в будущих обновлениях, в виде отправки повторной задачи воркерам на обновление кэша, по таймауту?..
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mailman.nginx.org/pipermail/nginx-ru/attachments/20190531/ab03da48/attachment-0001.html>
Подробная информация о списке рассылки nginx-ru