About 5 years ago I switched from Apache to Nginx. And with that switch I could practically stop stabbing my feet with HTTP accelerators like Squid and Varnish because Nginx serves files from the filesystem both faster and more efficient than the accelerators. And, it's one less moving part that can go wrong.
Then in late 2010 Amazon introduced Custom Origins on their Amazon CloudFront CDN service. Compared to other competing CDNs I guess CloudFront loses some benchmarks and win some others. Nevertheless, network latency is the speed-freaks biggest enemy and CDNs are awesome.
With Custom Origin all you do is tell CloudFront to act as a "proxy". It takes and URL and replaces the domain name to go and fetch the original from your own server. For example...
- You prepare
- You configure your CloudFront get your new domain (aka. "Distribution")
- You request
- CloudFront fetches the resource from
http://mydomain.com/static/foo.cssand saves a copy
- CloudFront observes which cache headers were used and repeat that. Forever.
So, if I make my Nginx server serve
Expires: Thu, 31 Dec 2037 23:55:55 GMT Cache-Control: max-age=315360000 Cache-Control: public
Then CloudFront will do the same and it means it will never come back to your Nginx again. In other words, your Nginx server serves the cacheable static assets once and all other requests are just the usual HTML and JSON and whatever your backend web server spits out.
So, what does this mean? It means that we can significantly re-think they way we write code that prepares and builds static assets. Instead of a complex build or a run-time process that ultimately writes files to the filesystem we can basically do it all in run-time and not worry about speed. E.g. something like this::
# urls.py url(r'/static/(.*\.css)', views.serve_css) # views.py def serve_css(request, filename): response = http.HttpResponse(mimetype="text/css") response.setHeader('Cache-Control': 'public, max-age:315360000') content = open(filename).read() content = cssmin.cssmin(content) content = '/* copyright: you */\n%s' % content response.write(content) return response
That's untested code that can be vastly improved but I hope you get the idea. Obviously there are lots more things you can and should do such concatenating files.
So, what does this also mean? You don't need Nginx. At least not for serving static files faster. I've shown before that something like Nginx + uWSGI is "better" (faster and less memory) than something like Apache + mod_wsgi but oftentimes the difference is negligable.
I for one am not going to re-write all my various code I have to prepare for optimal static assets hosting but I'll definietly keep this stuff in mind. After all, there are other nifty things Nginx can do too.
By the way, here's a really good diagram that explains CloudFront
Want to read this in Serbian? Thank you Anja Skrba for the translation!