Invision power board, кэширование, nginx и редиректы

// Ноябрь 21st, 2011 // PHP, Веб-разработка

В этом посте я расскажу о баге, который недавно правил. Проблема была в том, что nginx выдавал 404 ошибку при обращении к одной из внутренних страниц форума. Баг проявлялся временами, и обладал ещё рядом особенностей.

  1. Он проявлялся исключительно на сайте с движком IPB (Invision Power Board).
  2. После выключения кэширования в движке или перезапуске memcached работа была восстановлена.
  3. Баг воспроизводился только для внутренних страниц форума.
  4. Страничное кэширование в nginx было отключено.

С одной стороны можно было бы просто выключить кэширование на форуме, да и забыть об этом.

$INFO['use_memcache'] = 0; // Выключаем
$INFO['memcache_server_1'] = "127.0.0.1";
$INFO['memcache_port_1'] = "11211";

Однако, в этом случае сильно возрастает нагрузка на сервер, что в конечном счёте выливается во вполне реальные деньги. Так что надо бороться с причиной, а не с последствиями.

Подчистив логи nginx я воспроизвёл баг и начал смотреть в файлы журналов. Там, в error.log обнаружилась интересная запись:

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 строчку

server_name_in_redirect off;

и тогда nginx не будет использовать первое значение server_name для подстановки в адреса при редиректах, а все мы знаем, как IPB любит редиректы :-) Ну а можно просто поставить первым в списке нужный server_name.

Upstream sent too big header

Но моя радость была бы не полной, если бы не выплыл ещё один баг. В логах теперь отображается правильный server_name, однако сама ошибка никуда не исчезла. Вот она:

15907#0: *653303 upstream sent too big header while reading response header from upstream

Для её исправления надо было увеличить буферы nginx’у

fastcgi_buffers 8 32k;
fastcgi_buffer_size 32k;

Если nginx проксирует на apache, то нужно добавлять вот эти строки

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

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


Комментировать