Caching + Error_code inefficiences

Maxim Dounin mdounin at
Tue Aug 25 16:06:03 MSD 2009


On Tue, Aug 25, 2009 at 01:05:26AM -0400, icqheretic wrote:

> Sorry about the partial repost. I misclicked the POST button early on and ran into the edit restrictions. Disregard the top.
> Consider:
>      fastcgi_cache_path             storage/cache levels=2:2 keys_zone=cacheresp:50m inactive=25m max_size=2000M;
>      fastcgi_temp_path              storage/temp/;
>      fastcgi_cache_valid             any 10s;
>     location / {
>             root            html;
>             index           index.html;
>             fastcgi_pass    unix:/tmp/php-fcgi.socket
>             include        fastcgi_params;
>             fastcgi_cache          cfcheckresp;
>             error_page 404 = @backend;
>     }
>    location @backend {
>         proxy_pass;
>    }
> The idea is that if fastcgi returns a 404 then the backend handles the request. The backend's response should never be cached.  This part works great.  What doesn't... is that the 404 is never cached (the fastcgi script is hardcoded to always return "Cache-Control: max_age=5"). Fastcgi is consulted again and again when a 404 is hit. If any other code is hit it caches just fine for 5 full 5 seconds.  It would be great if the 404 result was cached. Any thoughts on accomplishing this? Am I missing something?
> By the way, the same goes if you use try_files() in place of error_page(). And I believe the same happens when a x-accel-redirect is issued.

With try_files fastcgi won't be reached at all if it won't found 
relevant file.

Redirected responses (either via error_page + 
fastcgi_intercept_errors, or via X-Accel-Redirect) can't be cached 
now since they leave upstream processing before place where saving 
to cache happens.

One possible workaround is to add extra proxy layer just to 
separate caching, e.g.

    location / {
        # redirection to backend happens here

        proxy_pass;  # same server
        proxy_intercept_errors on;
        error_page 404 = @backend;

    location /cache/ {
        # caching happens here

        fastcgi_pass ...
        fastcgi_cache ...
        fastcgi_intercept_errors off; # default, actually

        # For X-Accel-Redirect caching you also need to pass this 
        # header to upper proxy instead of processing right now. 
        # In nginx 0.8.7+ this can be done via
        # fastcgi_ignore_headers/fastcgi_pass_headers. In 
        # older versions (including 0.7.61) use another header 
        # name and add_header directive instead.

        fastcgi_ignore_headers X-Accel-Redirect;
        fastcgi_pass_headers X-Accel-Redirect;

    location @backend {

Maxim Dounin

More information about the nginx mailing list