【问题标题】:How do we configure symfony 1.4 to use it with Varnish?我们如何配置 symfony 1.4 以将其与 Varnish 一起使用?
【发布时间】:2012-01-04 03:27:39
【问题描述】:

昨天我的服务器负载很大,即使我之前致力于优化性能(大约 2 个月前我遇到过类似的问题),我的服务器也无法处理负载(我有一个服务每分钟创建大约 50 个帐户)。

最后,我的服务器处理了负载,因为我更改了实例:我在 Amazon EC2 上,我使用的是具有 20 个微型实例的负载均衡器。这还不够。我终于改成10个大实例了,没关系。 但是,你知道,大型实例有点贵,而且我买不起这么多大型实例(现在,因为负载较少,我“只”运行了 5 个大型实例,但也太多了)。

所以,我仍在优化和服务器配置,但我卡在一个点上。

到目前为止,我正在使用 symfony 和 memcached。它工作正常,所有应该缓存的东西都被缓存了,等等。

现在,我想在我的 apache Web 服务器前面添加一个 Varnish。

我这样做了,我配置了它——我想——好吧,它现在正在运行。问题是缓存没有命中。

据我所见,问题在于 symfony 发送的 HTTP 标头设置不正确。 例如,对于缓存的请求,我有以下标头:

    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 中为特定操作设置缓存头,但很明显,我不想在每个操作上都这样做(顺便说一下,即使我这样做了,我认为这不是正确的方法) .

所以我在问如何在 symfony 1.4 中使用 Varnish 就我所见,有两种可能:

  • 我正确设置了 symfony 发送的 HTTP 头
  • 我配置 Varnish 以正确处理 symfony 发送的默认 HTTP 标头

你知道我该如何解决其中一个问题吗?

谢谢,

注意: 我在 Varnish3 上

【问题讨论】:

  • +1 有趣的问题。我也将很快在 symfony 1.4 中使用 varnish。我有兴趣阅读答案。

标签: php apache http-headers symfony-1.4 varnish


【解决方案1】:

我终于自己找到了解决问题的方法,所以我将分享我是如何做到的:

首先,您应该知道 symfony 会在每次调用页面时自动创建一个 PHP 会话。所以,我所做的就是停用该默认行为。为此,我在 factory.yml 中添加了一个存储工厂(默认:sfSessionStorage),其中 auto_start 参数设置为 false

storage:
  class: sfSessionStorage
  param:
    auto_start: false

然后,我创建了一个过滤器来处理 http 标头:

我首先将它添加到 filters.yml 文件中

http_header:
  class: myHttpHeaderFilter

然后我在 lib 文件夹中添加了一个 myHttpHeaderFilter.php 类,我在其中处理了我想要的所有标题。例如:

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);
}

【讨论】:

  • 您好,您是如何使用 Varnish 管理 CSRF 令牌的?我们在每个页面(在模式上)都有一个登录表单,我们想使用 Varnish,但我们不确定如何避免出现问题。谢谢!
猜你喜欢
  • 2011-12-28
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 2012-04-28
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
相关资源
最近更新 更多