Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Varnish appears to be working but max-age=0

isvarnishworking.com is letting me know that

Varnish appears to be responding at that url, but the Cache-Control header's "max-age" value is less than 1, which means that Varnish will never serve content from cache at this url.

The max-age value appears to be: 0

And this header info

The url we checked: myDomainHere.com
    HTTP/1.1 200 OK
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By:   PHP/5.5.9-1ubuntu4.5
Set-Cookie: PHPSESSID=vgk7db66kh7nce8lpe5789u105; path=/
Expires:    Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:  max-age=60, private, proxy-revalidate
Pragma: no-cache
Vary:   Accept-Encoding,User-Agent
Content-Encoding:   gzip
Content-Type:   text/html
Content-Length: 14192
Accept-Ranges:  bytes
Date:   Sat, 18 Jul 2015 09:31:55 GMT
X-Varnish:  324589322
Age:    0
Via:    1.1 varnish
Connection: keep-alive

I have this in .htaccess

 <FilesMatch "\.(js|css)$">
    Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(html|htm|php)$">
    Header set Cache-Control "max-age=60, private, proxy-revalidate"
</FilesMatch>

So my question, Do I really have to change that max-age=0 in order to varnish perform better? If so, where would I Do this? I am using apache2 on a ubuntu digitalocean's droplet

-edit-

This is my /etc/varnish/default.vcl

# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition.  Set this to point to your content
# server.
#
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}
#
# Below is a commented-out copy of the default VCL logic.  If you
# redefine any of these subroutines, the built-in logic will be
# appended to your code.
# sub vcl_recv {
#     if (req.restarts == 0) {
#       if (req.http.x-forwarded-for) {
#           set req.http.X-Forwarded-For =
#               req.http.X-Forwarded-For + ", " + client.ip;
#       } else {
#           set req.http.X-Forwarded-For = client.ip;
#       }
#     }
#     if (req.request != "GET" &&
#       req.request != "HEAD" &&
#       req.request != "PUT" &&
#       req.request != "POST" &&
#       req.request != "TRACE" &&
#       req.request != "OPTIONS" &&
#       req.request != "DELETE") {
#         /* Non-RFC2616 or CONNECT which is weird. */
#         return (pipe);
#     }
#     if (req.request != "GET" && req.request != "HEAD") {
#         /* We only deal with GET and HEAD by default */
#         return (pass);
#     }
#     if (req.http.Authorization || req.http.Cookie) {
#         /* Not cacheable by default */
#         return (pass);
#     }
#     return (lookup);
# }
#
# sub vcl_pipe {
#     # Note that only the first request to the backend will have
#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to
#     # have it set for all requests, make sure to have:
#     # set bereq.http.connection = "close";
#     # here.  It is not set by default as it might break some broken web
#     # applications, like IIS with NTLM authentication.
#     return (pipe);
# }
#
like image 261
Toni Michel Caubet Avatar asked Jul 18 '15 09:07

Toni Michel Caubet


People also ask

How do I know if Varnish is working?

Open your browser's developer tools. Switch to the network view (where you should be able to inspect each network request) Inspect the headers of the request you want to check X-Varnish and X-Cache for (probably just the / or index page)…

How do I bypass Varnish Cache?

Bypassing the cache in Varnish is done by calling return (pass) in the vcl_recv subroutine of your VCL file. This return statement will send you to the vcl_pass subroutine where a backend fetch will be triggered instead of performing a cache lookup.

What is TTL in Varnish Cache?

TTL. Varnish object life time. In general, the time-to-life (TTL) of an object is set to the max-age value specified by application servers in the Cache-Control header.

Is Varnish Cache good?

Varnish is tremendously fast and relies on pthreads to handle a massive amount of incoming requests. The threading model and the use of memory for storage will result in a significant performance boost of your application. If configured correctly, Varnish Cache can easily make your website 1,000 times faster.


2 Answers

Do I really have to change that max-age=0 in order to varnish perform better?

Yes. You need to do it if you want it to perform at all.

If so, where would I Do this?

It seems you got everything right for caching static content, but you also seem to want to cache PHP script execution responses:

You are just missing session_cache_limiter and session_cache_expire, which should be the first lines executed on the requested PHP script, even before session_start().

If, for example, the content returned is private and you want to refresh it every minute, try something like:

session_cache_limiter('private');
session_cache_expire(1);

After that you should see a proper Cache-Control: max-age=60, private value on Varnish responses for requests for PHP generated content including those lines at the beginning of the script.

[update] Seeing your problem isn't solved yet, maybe you should try to use Apache mod_expires instead of manually setting the Cache-Control header: http://httpd.apache.org/docs/2.4/mod/mod_expires.html

That should answer your questions, but allow me to give you a few extra notes that may be useful to you and help you get a better understanding on how Varnish and the Cache-Control header relate to each other:

  • With the default configuration max-age=0 on the response indicates both to Varnish and to the browser that the response is not cacheable. Unless configured otherwise or explicitly allowed on the client's request, Varnish will not serve stale content:

A stale cache item will not be returned by any cache (proxy cache or client cache).

From https://www.rfc-editor.org/rfc/rfc7234#section-5.3:

If a response includes a Cache-Control field with the max-age
directive (Section 5.2.2.8), a recipient MUST ignore the Expires
field. Likewise, if a response includes the s-maxage directive
(Section 5.2.2.9), a shared cache recipient MUST ignore the Expires
field. In both these cases, the value in Expires is only intended
for recipients that have not yet implemented the Cache-Control field.

From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3:

If a cache returns a stale response, either because of a max-stale directive on a request, or because the cache is configured to override the expiration time of a response, the cache MUST attach a Warning header to the stale response, using Warning 110 (Response is stale).

A cache MAY be configured to return stale responses without validation, but only if this does not conflict with any "MUST"-level requirements concerning cache validation (e.g., a "must-revalidate" cache-control directive).

If both the new request and the cached entry include "max-age" directives, then the lesser of the two values is used for determining the freshness of the cached entry for that request.

  • The main purpose of Varnish is to store in-memory cacheable responses (while they are fresh) so they can be sent to the same OR different clients without regenerating them, also facilitating load balancing if required.

  • Varnish will not serve stale content when requested fresh content (most common scenario) and even if it did, the browser would not be saving it and would generate a new request for a fresh page every time the user asked for that content, unnecessarily hitting the cache (with all the network activity involved) instead of rendering a locally stored copy, which would be quite inefficient and noticeably slower!

max-age Indicates that the client is willing to accept a response whose age is no greater than the specified time in seconds. Unless max- stale directive is also included, the client is not willing to accept a stale response.

Now, if you still see the browser sends a new request every time the content is loaded (check the network tab of your browser's developer tools or varnish logs), recheck everything. As a last resort you can also try to set the proper html meta tags, although html5 deprecates them and they shouldn't be necessary for any modern browser and it is not best practice so I would advise against it.

Also here is some good reading on doing proper cache control on content generated by PHP scripts that might interest you.

like image 102
NotGaeL Avatar answered Sep 21 '22 06:09

NotGaeL


Your Varnish VCL is not sufficient. Search and use corresponding VCL 3 or VCL 4 template, according to your Varnish version.

Check your Varnish version: varnishd -V

If you use version 2, upgrade to version 3 or 4.

VCL for Varnish 3: https://github.com/dreamhost/varnish-vcl-collection

VCL for Varnish 4: https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/blob/master/default.vcl

like image 23
Domi Avatar answered Sep 21 '22 06:09

Domi