Назад | Перейти на главную страницу

Лакируйте прерывание входа в систему с помощью Invision Power Board

Недавно я перевел один из своих основных сайтов на установку WordPress, но, к сожалению, это привело к чрезвычайно высокой нагрузке на сервер. Изначально у меня был базовый сервер LAMP с несколькими сайтами. В первую очередь меня беспокоит сайт, который посещают около 60 000 человек в день и имеет очень активный форум, использующий Invision Power Board.

Это приводит меня туда, где я нахожусь сейчас. Я заменил apache на nginx, немного оптимизировал MySQL и установил Varnish. Это очень помогло и работает со всем, кроме моей установки Invision Power Board. По какой-то причине IPB больше не позволяет мне входить в систему или выходить из нее. На одном из моих компьютеров, на котором я вошел в систему, я могу оставаться в системе. Но если я попытаюсь войти в ACP или на форумы с другого компьютера или браузера, это не сработает. Ниже приведены мои настройки в Varnish:

sub vcl_recv {
   if (req.http.host ~ "^(www\.)?domain1\.net$") {
       set req.http.host = "domain1.net";
       set req.backend = domain1;
       return (lookup);
   }
   if (req.http.host == "old.domain1.net") {
       #You will need the following line only if your backend has multiple virtual host names
       set req.http.host = "old.domain1.net";
       set req.backend = olddomain1;
       return (lookup);
   }
   if (req.http.host ~ "^(www\.)?domain2\.net$") {
       set req.http.host = "domain2.net";
       set req.backend = domain2;
       return (lookup);
   }
   if (req.http.host ~ "^(www\.)?domain3\.com$") {
       set req.http.host = "domain3.com";
       set req.backend = domain3;
       return (lookup);
   }
   if (req.http.host ~ "^(www\.)?domain4\.org$") {
       set req.http.host = "domain4.org";
       set req.backend = domain4;
       return (lookup);
   }
}


# Drop any cookies sent to Wordpress.
sub vcl_recv {
    #exclusion for one domain that has low-views and maybe have unexpected results
    if (!(req.http.host ~ "^(www\.)?domain4\.org$")) {
        if (!(req.url ~ "wp-(login|admin)")) {
            if (!(req.url ~ "forums")) {
                    unset req.http.cookie;
            }
        }
    }
}

# Drop any cookies Wordpress tries to send back to the client.
sub vcl_fetch {
    #exclusion for one domain that has low-views and maybe have unexpected results
    if (!(req.http.host ~ "^(www\.)?domain4\.org$")) {
            if (!(req.url ~ "wp-(login|admin)")) {
                if (!(req.url ~ "forums")) {
                        unset beresp.http.set-cookie;
                }
            }
    }
}

Я новичок в nginx и лаке. Я видел еще один вопрос, но без хороших решений.

Во-первых - у вас два vcl_recv функции, вам необходимо объединить их в одну.

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

Сделайте тестовый вход без Varnish; когда Set-Cookie отправляется сервером? Найдите, где это происходит, затем снова попробуйте Varnish и посмотрите, Set-Cookie в этом случае отправляется правильно. Может быть, просто if (!(req.url ~ "forums")) { исключение не распространяется на ресурс, отправляющий cookie.

Вы делаете явный return(lookup) в вашем первом vcl_recv. Это означает, что код во втором блоке vcl_recv будет запускаться только в том случае, если запрос не соответствует ни одному из условий в первом блоке (т. Е. Если он не ^(((www\.|old\.)?domain1\.net)|((www\.)?domain(2\.net|3\.com|4\.org))$) и все остальные части второго vcl_recv if блоки успешно.

По сути, вы переопределяете здесь совершенно хорошую встроенную логику Varnish, которая передавала бы запросы для вошедших в систему пользователей (то есть тех, которые имеют файлы cookie) на бэкэнд, а остальную часть обслуживаете из кеша, если таковой имеется. Вы можете получить желаемый результат, просто удалив все return(lookup)с. Но если вы настаиваете на том, чтобы сделать это текущим способом, вам просто нужно добавить:

sub vcl_hash {
  if ( req.http.Cookie ) {
    hash_data( req.http.Cookie );
  }
}

Преимущество переопределения логики Varnish состоит в том, что даже файлы cookie, которые не имеют никакого отношения к обработке запроса сервером, например идентификаторы urchin в Google Analytics, будут вызывать попадание каждого запроса в серверную часть. Чтобы избежать этого, либо занесите в белый список файлы cookie, которые важны для сервера, либо внесите в черный список те, которые ему не нужны; ряд методов для достижения этой цели доступен в Интернете и на https://www.varnish-cache.org/ .

Изменить: немного расширившись, здесь происходит то, что вы говорите Varnish о том, что, если запрос поступает, скажем, для домена 1, затем использовать бэкэнд домена 1, а затем попытаться получить этот объект из кеша. Если его нет в кеше, он получит его из серверной части и сохранит в кеше. Пока в ответе нет заголовка Set-Cookie (который в default.vcl приводит к тому, что объект становится не кэшируемым), в следующий раз, когда кто-то запросит ту же страницу, он увидит ее как тот пользователь (или какой «не пользователь», если кто-то не вошел в систему) видел его последним, предполагая, что TTL еще не истек. Что мы делаем с vcl_hash код сообщает Varnish о том, что он должен рассматривать кешированные объекты, отличные от Cookie, доставленного с запросом. Мы могли бы легко улучшить это - например, мы могли бы заботиться только о cookie для страниц, которые не заканчиваются на \.(jpg|png|gif|AndSoForth)$, но правильное место для этого находится в vcl_recv, где мы должны просто полностью удалить заголовок Cookie для таких запросов.