Как настроить Symfony 1.4 для использования с Varnish? - PullRequest
4 голосов
/ 22 ноября 2011

Вчера у меня была огромная нагрузка на мои серверы, и, даже если я раньше работал над оптимизацией производительности (у меня была похожая проблема около 2 месяцев назад), мои серверы не могли справиться с нагрузкой (у меня есть служба, котораяоколо 50 созданий учетных записей в минуту).

Наконец, мои серверы обрабатывали нагрузку, потому что я изменил экземпляры: я нахожусь на Amazon EC2, и я использовал балансировщик нагрузки с 20 микроэлементами.Этого было недостаточно.Я наконец изменился на 10 больших экземпляров, и это было нормально.Но, вы знаете, большие экземпляры являются довольно дорогими, и я не могу позволить себе иметь так много больших экземпляров (сейчас, поскольку нагрузка меньше, у меня «работает» только 5 больших экземпляров, но это тоже слишком много).

Итак, я все еще работаю над оптимизацией и настройкой сервера, но я застрял на точке.

Пока что я использую Symfony с memcached.Он работает нормально, все, что должно быть кэшировано, кэшируется и т. Д.

Теперь я хочу добавить Varnish перед моим веб-сервером apache.

Я сделал это и настроил его- Я думаю - хорошо, и это работает сейчас.Проблема в том, что в кэш-памяти нет попаданий.

Из того, что я видел, проблема в том, что HTTP-заголовки, отправляемые Symfony, установлены неправильно.Например, для кэшированного запроса у меня есть следующие заголовки:

    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache

Модуль правильно настроен для использования кэша и т. Д., Но я просто не могу найти, где я могу установить правильные заголовки HTTP,Я знаю, как установить заголовок кэша в Symfony для конкретного действия, но ясно, что я не хочу делать это при каждом действии (кстати, даже если я это сделал, я думаю, что это не правильный путь).

Поэтому я спрашиваю, как я могу использовать Varnish с Symfony 1.4. Из того, что я видел, есть две возможности:

  • Я правильно установил заголовки HTTP, отправленные Symfony
  • Я настраиваю Varnish для правильной обработки заголовков HTTP по умолчанию, отправляемых symfony

Знаете ли вы, как можно устранить одну из проблем?

Спасибо,

Примечание: я нахожусь на Лаке 3

1 Ответ

6 голосов
/ 24 ноября 2011

Я наконец-то сам нашел, как решить мою проблему, поэтому я поделюсь, как я это сделал:

Для начала вы должны знать, что symfony автоматически создает сеанс PHP при каждом вызове страницы. Итак, я деактивировал это поведение по умолчанию. Для этого я добавил в factories.yml фабрику хранения (по умолчанию: sfSessionStorage) с параметром auto_start , установленным в false :

storage:
  class: sfSessionStorage
  param:
    auto_start: false

Затем я создал фильтр для обработки заголовков http:

Сначала я добавил его в файл filters.yml

http_header:
  class: myHttpHeaderFilter

А затем я добавил класс myHttpHeaderFilter.php в папку lib, где я обработал все нужные заголовки. Например:

class myHttpHeaderFilter extends sfFilter
{
    public function execute($filterChain)
    {
      //execute the next filter in the chain
      $filterChain->execute();
      //code after here runs after action

      // Filters don't have direct access to the request and user objects.
      // You will need to use the context object to get them
      $request = $this->getContext()->getRequest();
      $path = $request->getPathInfo();

      if (substr($path, 0, 5) == "/foo") // We cache only some of the /foo requests
      {
          if (strstr($path, "bar")) // We cache the request containing bar during half an hour hour
              $this->getContext()->getResponse()->addCacheControlHttpHeader('max-age=1800');
          else // All the other requests are cached during 24 hours
          {
              $this->getContext()->getResponse()->addCacheControlHttpHeader('max-age=86400');
          }
      }
      else // The other requests are not cached
          $this->getContext()->getResponse()->addCacheControlHttpHeader('no-cache, no-store');
    }
}

И это было все!

Я также изменил vcl_recv на стороне сервера, чтобы гарантировать, что все запросы, которые не нужно кэшировать, не являются (теоретически это не обязательно делать, потому что я обработал его в Symfony, это просто " перепроверить ").

sub vcl_recv {
     if (req.http.Authorization || req.http.Cookie) {
         /* Not cacheable by default */
         return (pass);
     }

     if (req.request != "GET" && req.request != "HEAD") {
         /* We only deal with GET and HEAD by default */
         return (pass);
     }

     if (req.url ~ "/user") /* Requests containing user data are never cached */
        {
                return (pass);
        }

     return (lookup);
}
...