Difference between revisions of "Nginx/Caching"

From WhyAskWhy.org Wiki
Jump to: navigation, search
m (Removed proxy_cache settings since they did not directly apply to what I'm testing right now.)
m (Added http/server sections in the hopes that it would be easier to follow. Also added more references, cache settings and log format used.)
Line 22: Line 22:
 
Parameters of caching can also be set directly in the response header. This has a higher precedence than setting of caching time using the directive. The <code>X-Accel-Expires</code> header field sets caching time of a response in seconds. '''The value 0 disables the caching of a response'''. If a value starts with the prefix <code>@</code>, it sets an absolute time in seconds since Epoch, up to which the response may be cached. If header does not include the <code>X-Accel-Expires</code> field, parameters of caching may be set in the header fields <code>Expires</code> or <code>Cache-Control</code>. If a header includes the <code>Set-Cookie</code> field, such a response will not be cached. Processing of one or more of these response header fields can be disabled using the <code>proxy_ignore_headers</code> directive.
 
Parameters of caching can also be set directly in the response header. This has a higher precedence than setting of caching time using the directive. The <code>X-Accel-Expires</code> header field sets caching time of a response in seconds. '''The value 0 disables the caching of a response'''. If a value starts with the prefix <code>@</code>, it sets an absolute time in seconds since Epoch, up to which the response may be cached. If header does not include the <code>X-Accel-Expires</code> field, parameters of caching may be set in the header fields <code>Expires</code> or <code>Cache-Control</code>. If a header includes the <code>Set-Cookie</code> field, such a response will not be cached. Processing of one or more of these response header fields can be disabled using the <code>proxy_ignore_headers</code> directive.
 
</blockquote>
 
</blockquote>
 +
 +
=== http section ===
 +
 +
==== Logging cache hits/misses ====
 +
 +
The following log format <ref name="log-format" /> is used to help troubleshoot what content is and isn't being cached.
 +
 +
Here is what I'm using for now:
 +
 +
<syntaxhighlight lang="nginx">
 +
log_format cache '***$time_local '
 +
    '$upstream_cache_status '
 +
    'Cache-Control: $upstream_http_cache_control '
 +
    'Expires: $upstream_http_expires '
 +
    '$host '
 +
    '"$request" ($status) '
 +
    '"$http_user_agent" '
 +
    'Args: $args '
 +
    'HTTP Cookie: $http_cookie ';
 +
</syntaxhighlight>
 +
 +
 +
==== Cache path ====
 +
 +
Setup cache <ref name="cache-path-explanation" /> for later use in server block(s):
 +
 +
<syntaxhighlight lang="nginx">
 +
    fastcgi_cache_path /var/cache/nginx/
 +
        levels=1:2 keys_zone=fastcgi_cache:8m max_size=250m inactive=3d;
 +
    fastcgi_temp_path /var/cache/nginx/tmp;
 +
</syntaxhighlight>
 +
 +
 +
=== server section ===
 +
 +
==== Using the cache log ====
 +
 +
We defined it earlier, and now will use it in a server block (I still think of them as vhost blocks from my dealings with Apache HTTPd) where we're testing the various cache settings:
 +
 +
<syntaxhighlight lang="nginx">
 +
server {
 +
    ...
 +
    access_log /var/log/nginx/testing.cache.log cache;
 +
    ...
 +
}
 +
</syntaxhighlight>
  
  
Line 29: Line 75:
  
 
<syntaxhighlight lang="nginx">
 
<syntaxhighlight lang="nginx">
 
+
server {
 +
    ...
 
     # Nested location block (PHP/FastCGI content)
 
     # Nested location block (PHP/FastCGI content)
  
Line 44: Line 91:
 
         location ~ \.php$  
 
         location ~ \.php$  
 
         {
 
         {
 
 
           # Placing these in a separate file for now so they can be referenced
 
           # Placing these in a separate file for now so they can be referenced
 
           # directly when needed (until I learn of a better way)
 
           # directly when needed (until I learn of a better way)
Line 54: Line 100:
 
          
 
          
 
     }
 
     }
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 61: Line 108:
  
 
<syntaxhighlight lang="nginx">
 
<syntaxhighlight lang="nginx">
 +
server {
 +
    ...
 
     # Location blocks on the same level
 
     # Location blocks on the same level
  
Line 83: Line 132:
 
       include proxy.inc.conf;
 
       include proxy.inc.conf;
 
     }
 
     }
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
== References ==
 
== References ==
  
 +
<references>
 +
<ref name="log-format">[http://blog.infoentropy.com/Custom_Nginx_logging_format infoentropy.com - Custom nginx logging format (cache log)]</ref>
 +
<ref name="cache-path-explanation">[http://www.djm.org.uk/wordpress-nginx-reverse-proxy-caching-setup/ www.djm.org.uk - Using Nginx as a reverse caching proxy for Wordpress: the setup]</ref>
 
<references />
 
<references />
  

Revision as of 06:13, 19 August 2012



Pay close attention to what version of nginx a book or web resource is based on as behavior may change between releases [1]


For the last few weeks I've been trying to figure out how to properly configure caching for nginx sites and have had hit/miss (pun intended) results. The notes here are my attempt to keep up with what has worked so I can go from there.

Caching FastCGI content

From the FastCGI module wiki page:

The cache honors backend's Cache-Control, Expires, and etc. since version 0.7.48, Cache-Control: private and no-store only since 0.7.66, though. Vary handling is not implemented.

From the http_proxy_module page:

Parameters of caching can also be set directly in the response header. This has a higher precedence than setting of caching time using the directive. The X-Accel-Expires header field sets caching time of a response in seconds. The value 0 disables the caching of a response. If a value starts with the prefix @, it sets an absolute time in seconds since Epoch, up to which the response may be cached. If header does not include the X-Accel-Expires field, parameters of caching may be set in the header fields Expires or Cache-Control. If a header includes the Set-Cookie field, such a response will not be cached. Processing of one or more of these response header fields can be disabled using the proxy_ignore_headers directive.

http section

Logging cache hits/misses

The following log format [2] is used to help troubleshoot what content is and isn't being cached.

Here is what I'm using for now:

log_format cache '***$time_local '
    '$upstream_cache_status '
    'Cache-Control: $upstream_http_cache_control '
    'Expires: $upstream_http_expires '
    '$host '
    '"$request" ($status) '
    '"$http_user_agent" '
    'Args: $args '
    'HTTP Cookie: $http_cookie ';


Cache path

Setup cache [3] for later use in server block(s):

    fastcgi_cache_path /var/cache/nginx/
        levels=1:2 keys_zone=fastcgi_cache:8m max_size=250m inactive=3d;
    fastcgi_temp_path /var/cache/nginx/tmp;


server section

Using the cache log

We defined it earlier, and now will use it in a server block (I still think of them as vhost blocks from my dealings with Apache HTTPd) where we're testing the various cache settings:

server {
    ...
    access_log /var/log/nginx/testing.cache.log cache;
    ...
}


What works

So far I've determined that a nested setup works:

server {
    ...
    # Nested location block (PHP/FastCGI content)

    location /
    {
        fastcgi_cache fastcgi_cache;
        fastcgi_cache_valid 200 302 3d;
        fastcgi_cache_valid 404 1m;
        fastcgi_cache_use_stale   error timeout invalid_header http_500;
        fastcgi_cache_key   "$scheme$request_method$host$uri$is_args$args";
        
        # Will content be cached if embedded within another location block?
        # In this configuration, the answer is yes.
        location ~ \.php$ 
        {
           # Placing these in a separate file for now so they can be referenced
           # directly when needed (until I learn of a better way)
           include php_parameters.conf;

           # Misc general FastCGI and Proxy settings.
           include proxy.inc.conf;
        }
        
    }
}

What does not work

Not all that surprising, but this does not result in cached FastCGI (PHP) content:

server {
    ...
    # Location blocks on the same level

    location /
    {
        fastcgi_cache fastcgi_cache;
        fastcgi_cache_valid 200 302 3d;
        fastcgi_cache_valid 404 1m;
        fastcgi_cache_use_stale   error timeout invalid_header http_500;
        fastcgi_cache_key   "$scheme$request_method$host$uri$is_args$args";
    }

    # Content matching this location block will not be cached
    location ~ \.php$ 
    {

       # Placing these in a separate file for now so they can be referenced
       # directly when needed (until I learn of a better way)
       include php_parameters.conf;

       # Misc general FastCGI and Proxy settings.
       include proxy.inc.conf;
    }
}

References

<references> [2] [3]

  1. In versions from 0.7.1 to 0.8.41, if a request matched the prefix location without the "=" and "^~" prefixes, the search also terminated and regular expressions were not checked.
  2. 2.0 2.1 infoentropy.com - Custom nginx logging format (cache log)
  3. 3.0 3.1 www.djm.org.uk - Using Nginx as a reverse caching proxy for Wordpress: the setup