Invision power board, кэширование, nginx и редиректы
В этом посте я расскажу о баге, который недавно правил. Проблема была в том, что nginx выдавал 404 ошибку при обращении к одной из внутренних страниц форума. Баг проявлялся временами, и обладал ещё рядом особенностей.
- Он проявлялся исключительно на сайте с движком IPB (Invision Power Board).
- После выключения кэширования в движке или перезапуске memcached работа была восстановлена.
- Баг воспроизводился только для внутренних страниц форума.
- Страничное кэширование в nginx было отключено.
С одной стороны можно было бы просто выключить кэширование на форуме, да и забыть об этом.
1 2 3 |
$INFO['use_memcache'] = 0; // Выключаем $INFO['memcache_server_1'] = "127.0.0.1"; $INFO['memcache_port_1'] = "11211"; |
Однако, в этом случае сильно возрастает нагрузка на сервер, что в конечном счёте выливается во вполне реальные деньги. Так что надо бороться с причиной, а не с последствиями.
Подчистив логи nginx я воспроизвёл баг и начал смотреть в файлы журналов. Там, в error.log обнаружилась интересная запись:
1 |
2011/11/20 09:39:00 [error] 15907#0: *653303 upstream sent too big header while reading response header from upstream, client: 81.145.110.213, server: site.ru, request: "GET /index.php?showforum=9&s=a27c0252d9c97966ea9d5293f7bbfd47 HTTP/1.1", upstream: "fastcgi://127.0.0.1:9010", host: "forum.ru", referrer: "http://forum.ru/" |
А интересного в ней то, что я обращался к сайту forum.ru, а в записи фигурирует site.ru, который также обслуживается на этом сервере.
Гугление проблемы привело меня в тред Possible bug? Redirect 301 to 1st hostname in server_name list на форуме nginx. Суть бага заключается вот в чём:
When requesting host3/drupal
nginx sends http 301 and the browser is redirected to host1/drupal
(which is on another server).
У меня ситуация аналогичная. Сайт site.ru стоит первым в списке server_name в конфиге nginx, а запрос идёт на forum.ru, который болтается где-то в середине.
Решение
Чтобы вылечить данный баг, надо добавить в конфиг nginx строчку
1 |
server_name_in_redirect off; |
и тогда nginx не будет использовать первое значение server_name для подстановки в адреса при редиректах, а все мы знаем, как IPB любит редиректы 🙂 Ну а можно просто поставить первым в списке нужный server_name.
Upstream sent too big header
Но моя радость была бы не полной, если бы не выплыл ещё один баг. В логах теперь отображается правильный server_name, однако сама ошибка никуда не исчезла. Вот она:
1 |
15907#0: *653303 upstream sent too big header while reading response header from upstream |
Для её исправления надо было увеличить буферы nginx’у
1 2 |
fastcgi_buffers 8 32k; fastcgi_buffer_size 32k; |
Если nginx проксирует на apache, то нужно добавлять вот эти строки
1 2 |
proxy_buffers 8 16k; proxy_buffer_size 32k |
Удачи вам, коллеги веб-девелоперы!
Ссылки
http://sklavyvbrauzer.blogspot.com/2011/09/upstream-sent-too-big-header-while.html
http://wiki.nginx.org/HttpCoreModule#server_name_in_redirect
http://forum.nginx.org/read.php?2,154025,154036
Очень интересно! Спасибо!