Tal*_*OUI 4 php apache varnish http-headers symfony-1.4
昨天我的服务器上有很大的负载,即使我之前曾在优化性能(我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
Run Code Online (Sandbox Code Playgroud)
模块已正确配置为使用缓存等,但我无法找到可以设置正确HTTP标头的位置.我知道如何在symfony中为特定操作设置缓存头,但显然,我不想在每个操作上都这样做(顺便说一下,即使我这样做了,我认为这不是正确的方法) .
所以我问如何在symfony 1.4中使用Varnish.从我看到的,有两种可能性:
你知道我怎么能解决其中一个问题?
谢谢,
注意:我在Varnish3上
我终于找到了自己如何解决我的问题,所以我将分享我是如何做到的:
首先,您应该知道每次调用页面时symfony都会自动创建一个PHP会话.所以,我所做的是停用该默认行为.为此,我在factories.yml上添加了一个存储工厂(默认值为:sfSessionStorage),auto_start参数设置为false:
storage:
class: sfSessionStorage
param:
auto_start: false
Run Code Online (Sandbox Code Playgroud)
然后,我创建了一个过滤器来处理http标头:
我首先将它添加到filters.yml文件中
http_header:
class: myHttpHeaderFilter
Run Code Online (Sandbox Code Playgroud)
然后我在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');
}
}
Run Code Online (Sandbox Code Playgroud)
就是这样!
我还修改了服务器端的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);
}
Run Code Online (Sandbox Code Playgroud)