On the homepage of nxing wiki, there used to be one sentence which really impressed my very much when I first time to take a look at it and learn it three years ago:
Apache is like Microsoft Word, it has a million options but you only need six. Nginx does those six things, and it does five of them 50 times faster than Apache. --Chris Lea
Now it is not there anymore, how you can still search on the web to see it: example link.
One of the six things nginx can do and can do gorgeous is putting it in front of the web application server as a Cache Reverse Proxy, which does two major tasks:
What are the benefits of doing this? There are many, items below are copied from Wikepedia:
- Reverse proxies can hide the existence and characteristics of the origin server(s).
- Application firewall features can protect against common web-based attacks. Without a reverse proxy, removing malware or initiating takedowns, for example, can become difficult.
- In the case of secure websites, the SSL encryption is sometimes not performed by the web server itself, but is instead offloaded to a reverse proxy that may be equipped with SSL accelerationhardware. (See SSL termination proxy)
- A reverse proxy can distribute the load from incoming requests to several servers, with each server serving its own application area. In the case of reverse proxying in the neighborhood of web servers, the reverse proxy may have to rewrite the URL in each incoming request in order to match the relevant internal location of the requested resource.
- A reverse proxy can reduce load on its origin servers by caching static content, as well as dynamic content. Proxy caches of this sort can often satisfy a considerable amount of website requests, greatly reducing the load on the origin server(s). Another term for this is web accelerator.
- A reverse proxy can optimize content by compressing it in order to speed up loading times.
- In a technique known as "spoon feeding", a dynamically generated page can be produced all at once and served to the reverse-proxy, which can then return it to the client a little bit at a time. The program that generates the page is not forced to remain open and tying up server resources during the possibly extended time the client requires to complete the transfer.
- Reverse proxies can be used whenever multiple web servers must be accessible via a single public IP address. The web servers listen on different ports in the same machine, with the same local IP address or, possibly, on different machines and different local IP addresses altogether. The reverse proxy analyzes each incoming call and delivers it to the right server within the local area network.
This post is focused on No 1 and 2 with dynamica content from backend web server, No 3 is simple enough, nginx provides a HTTP UPSTREAM module for doing it.
Image there is a web resource which is frequenyly accessed, and is less frequently updated, but it does cares about
instantaneity, for example:
For this kind of scenario, our idea scenario is:
Nginx can cache the resource, and it will refresh the cache as soon as the resource got updated, so that all the further requests will retrieve the latest version!
I built up a Rails 3, it expose a resource: http://localhost:3000/doc, it is very simple, each time a GET request comes in, it read a JSON file stored on hard disk:
And each time a POST request comes in, it update the Counter to plus one.
The view and edit actions in controller:
The simple view which renders JSON :
The rails server is bound to port 3000, and I am now going to config my nginx, my nginx.config is located at
The explanation is below:
Refer more information about the nginx proxy module config on: http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Now if I restart my nginx server: sudo nginx -s reload, and visit http://localhost/doc, I can see the JSON with Counter equals to 1 rendered on the web page:
And if we cd into /var/www/cache, we can see nginx has cached the request:
Important notice here: nginx will honor HTTP
Cache-Control header, i.e. if its value is set to "no-cache" or "private", nginx will NOT cache the response!
Now I am going to update the Counter:
And when I visit http://localhost/doc again, no doubt, I will see Counter is "1" since I've let nginx to cache it.
Important notice here: after nginx cache the resource inbound with an HTTP verb, any further request with the same HTTP verb on this resource will be responded by nginx, backend server will never got hit!
Now comes to the key point, by default nginx will pass any HTTP POST request to the backend without looking up the cache, so I can "purge" the nginx cache for specific resource, so that next time when a new request comes in, nginx will rebuild the cache!
The tool for purging nginx cache is a CLI tool called nginx-cache-purge.
The usage is:
nginx-cache-purge "foobar.cs" /var/www/cache/nginx/baz
So that I can add a invoking line in my "
edit" action inside my doc controller:
Now every time we edit the Counter by HTTP POST, the Rails app will invoke CLI to purge the "/doc" cache, so that next request will lead nginx to re-cache it, we are all set!
Actually nginx provide a standard HTTP API to purge the cache, that is proxy_cache_bypass module, it allows website administrators to define customized interface to bypass nginx cache look up, in my nginx.conf above there are two lines:
proxy_cache_bypass $http_secret_header; add_header X-Cache-Status $upstream_cache_status;
So if any client fires a HTTP request that contains header
Secret-Header: 1, nginx will bypass the request regardless of whether the requested resource was cached or not.
nginx is really a powerful and fast web server, and it is easy to use and config as well! Using nginx as a Cache Reverse Proxy can dramatically improve your website's loading speed and concurrency performance, thus improves UX and lower down the server cost. That's why it is used by so many popular websites.
https://github.com/FRiCKLE/ngx_cache_purge/ A nginx purge model