RESTful page caching met Nginx
Geplaatst door Matthijs Langenberg vr, 08 feb 2008 16:17:00 GMT
Op onze interne testomgeving bij Newminds maken we gebruik van Nginx als frontend webserver. Elke binnenkomende request wordt door Nginx doorgestuurd naar een mongrel proces. Onlangs heb ik rails page caching ingeschakeld en in dit artikel wil ik mijn ervaringen graag met je delen.
In dit artikel zal ik beschrijven wat er in het ‘server’ blok van de nginx configuratie gezet moet worden om statische files (die door rails worden gegenereerd) direct vanaf het bestandsysteem te versturen. Hierbij ga ik er vanuit dat je bekend bent met de configuratie files die nginx gebruikt, als je hier niet bekend mee bent zou je Ezra Zygmuntowicz’s voorbeeld Nginx configuratie kunnen bekijken.
Laten we eenvoudig beginnen:
server {
location / {
proxy_pass http://mongrel
}
}
Dit zal alle binnenkomende requests direct doorsturen naar de mongrel server. Dat is op zich goed, maar op deze wijze zullen er geen statische files door Nginx geserveerd worden, maar door het (trage) mongrel proces. Om dat te kunnen doen moeten we het bovenstaande blok uitbreiden.
server {
# specify document root
# see: http://wiki.codemongers.com/NginxHttpCoreModule#root
root /home/user/apps/my_app/current/public;
location / {
# if the file exists as a static file serve it directly
if (-f $request_filename) {
break;
}
# check for index.html for directory index
# if it's there on the filesystem then rewrite
# the url to add /index.html to the end of it
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
# add .html to the end of the url and check the filesystem
# if it exists, serve it directly, else hit mongrel
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (-f $request_filename) {
proxy_pass http://mongrel;
break;
}
}
Nu worden de statische files direct vanaf de harde schijf door Nginx verstuurd, zodat de applicatie super snel is!
Er is alleen een klein probleem: een request naar GET /fruits/23
zal public/fruits/23.html
rechtstreeks vanaf het bestandsysteem versturen. Dat werkt zoals bedoeld, maar wanneer iemand dit stuk fruit wil updaten zal er een request naar PUT /fruits/23
worden gestuurd. Wanneer dat gebeurd zal Nginx het bestandsysteem checken op het bestaan van een bestand op public/fruits/23.html
, dit bestand zal natuurlijk bestaan en Nginx stopt met het uitvoeren van de configuratie. Deze PUT
request zal nooit bij mongrel aankomen. Sterker nog, Nginx zal een 405 Method Not Allowed
HTTP status code terug geven, omdat Nginx alleen weet wat er met een GET
op een bestand gedaan moet worden, en niet wat er met een PUT
gedaan moet worden.
Dit houdt in dat we de configuratie moeten aanpassen zodat Nginx alleen een statische file zal proberen te versturen wanneer de HTTP method een GET
of een HEAD
is. Dit leidt ons tot de uitendelijke versie van het Nginx server configuratie blok, die alle request, behalve GET
of HEAD
requests direct naar mongrel doorstuurd.
server {
# specify document root
# see: http://wiki.codemongers.com/NginxHttpCoreModule#root
root /home/user/apps/my_app/current/public;
location / {
# only try to serve a static file if the request method is GET or HEAD
# if it's anything else (POST for example) hit mongrel.
if ($request_method !~ "GET|HEAD") {
proxy_pass http://mongrel;
break;
}
# if the file exists as a static file serve it directly
if (-f $request_filename) {
break;
}
# check for index.html for directory index
# if it's there on the filesystem then rewrite
# the url to add /index.html to the end of it
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
# add .html to the end of the url and check the filesystem
# if it exists, serve it directly, else hit mongrel
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (-f $request_filename) {
proxy_pass http://mongrel;
break;
}
}
Laat me het even weten wanneer dit artikel bruikbaar voor je was.