11

I need to nginx proxy use cache if backend server down:

this is my configuration. but seems be nginx use cache without check backend server.

http {

  # ...

  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_cache_path /tmp/nginx levels=1:2 keys_zone=tmpzone:10m inactive=60m;
  proxy_cache_key "$scheme$request_method$host$request_uri";


  server {
    server_name _;

    location / {
      proxy_connect_timeout 5s;
      proxy_read_timeout 5s;
      proxy_cache tmpzone;
      proxy_cache_valid      200 304 1d;
      proxy_cache_use_stale  error timeout invalid_header updating http_500 http_502 http_503 http_504;
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header Host 'www.example.com';
      proxy_pass http://www.example.com;
    }
  }
}

Question is how can i bypass the proxy cache if backend server is up ? And when backend server is up my proxy server dont use cache at all.

sweb
  • 451
  • 1
  • 9
  • 27
  • What exactly is the question? – Jenny D Jan 30 '16 at 12:44
  • Question is how can i bypass the proxy cache if backend server is up ? – sweb Jan 30 '16 at 14:55
  • One out of the box solution might be to have 2 "servers" running, one with cache, one w/o cache, and use upstream module http://nginx.org/en/docs/http/ngx_http_upstream_module.html ? The best solution would probably to be able to use proxy_cache_bypass with a check if the backend is there or not... though I have no idea how to get that working ... interesting case. – SvennD Feb 03 '16 at 13:56
  • Solutions to this instance of an XY Problem can be [found over on SO](https://stackoverflow.com/a/52232860/891636) – Dayo Sep 08 '18 at 07:15

2 Answers2

8

Seems a duplicate of this:

https://stackoverflow.com/questions/16756271/how-to-configure-nginx-to-serve-cached-content-only-when-backend-is-down-5xx-re

In short, use proxy_cache_use_stale

As an update, i tested this and it works fine. I did the test in my workstation where i have (for completeness):

Fedora 23 nginx 1.8.1 configured as ssl terminator + cache + reverse proxy Apache 2.4.18 configured to listen at port 80

With apache acting as upstream, serving just a static file i did this test:

  1. Apache up, nginx up, pointing the browser to the reverse proxied URL served by nginx i see the proxied content from Apache. At this point nginx keeps this on cache.
  2. Stopped apache
  3. connecting to nginx i see the cached file as served before by Apache.

The nginx config i used is (only the interesting parts):

nginx.conf :

http {
[...]
location
    proxy_cache_path        /var/lib/nginx/tmp/proxy/ levels=1:2 keys_zone=STATIC:10m inactive=24h max_size=1g;
    include /etc/nginx/conf.d/*.conf;
}

/etc/nginx/conf.d/local.conf :

upstream localhost {
    server 127.0.0.1:80;
[...]
}


server {
    listen       127.0.0.1:443 ssl;

[...]

    location /be/ {
        proxy_pass              http://localhost;
        proxy_cache             STATIC;
        proxy_cache_valid       200 1d;
        proxy_cache_use_stale   error;
}
Fredi
  • 2,227
  • 9
  • 13
  • Not work at all try it. – sweb Feb 09 '16 at 06:29
  • In case you should report a bug to the nginx team. What did you tried btw? In case i'll try to reproduce it – Fredi Feb 09 '16 at 13:10
  • Ok, i did a test and it worked fine. Updated my answer with the test details. – Fredi Feb 09 '16 at 15:10
  • So my reading of sweb's original question was that, in the state of both Apache and nginx up, _all_ requests should go through to the Apache backend. Requests should only be served from NginX cache iff Apache is down – abhishekmukherg Nov 30 '16 at 17:27
  • @abhishekmukherg, you can do what you say, but why? When both are up and the files are static (think jpg / css / html ) why going to the backend using more network / cpu / ecc resources when you have an actual frontend? BTW this is a matter for another question though – Fredi Dec 01 '16 at 10:43
  • @Fredi Well the original question does say "How can I bypass the proxy cache if backend server is up?" which is what abhishekmukherg is asking. The case I came here looking to solve is an API response that we would like to be fresh whenever possible, but if there is some upstream outage stale data will do. – Toby Dec 01 '16 at 13:21
  • @abhishekmukherg, nope, the title here is the opposite, copy and pasted: **nginx use proxy cache if backend is down**. And BTW, your use case is even simpler, just change your ErrorDocument pages so when your BE is down you print a pretty page or such. Whatever, you can open another question – Fredi Dec 01 '16 at 13:27
  • @Fredi You're totally right, I got this question messed up in my head with the one you linked and ended up commenting on the wrong one XD – abhishekmukherg Dec 01 '16 at 15:57
  • I do think the title of this question doesn't actually match the description in the question, though. It seems the title should be: nginx use proxy cache *only* if [the] backend is down – abhishekmukherg Dec 01 '16 at 16:03
0

Use proxy_intercept_errors and proxy 500s to a server that has caching enabled.

sysadmin1138
  • 131,083
  • 18
  • 173
  • 296
chugadie
  • 201
  • 1
  • 5