I have the installation with Apache2, nginx and Varnish above them. Varnish receives the request, determines what backend is it for (static goes to nginx, dynamic goes to Apache), fetches the response from backend and caches it if needed.
Amongst other things Apache generates thumbnails. It creates thumbnails using some specific logic and it is quite expensive for processor. Thus Apache saves thumb to disk in order next time the request for this thumbnail will be received Varnish could redirect it directly to nginx.
And here is a problem: Varnish has no way to check if file exists somewhere in file system and that's why it don't know if nginx backend can be used or Apache should generate thumbnail first.
The workaround which I've currently adopted is quite simple but ugly:
- Varnish receives the request for thumbnail;
- Varnish sends request to nginx;
- If nginx can't find thumbnail file it replies with 404 error and Varnish redirects request to Apache.
While this algorithm seems to be simple in reality it is not. Following implementation is needed in VCL configuration file:
- In
vcl_recv
always assume that thumbnail exists and all request must be redirectedto nginx if it is not requested from some special host; - In
vcl_fetch
catch object HTTP status and if it is 404 and resource is thumbnail than rewrite host to special one and restart the process:
VCL:
if( obj.status == 404 ) {
if(req.url ~ "^thumb/") {
set req.http.host = "thumb_generator.site.com";
set req.url = regsub(req.url, "/thumb/(filename)", "thumb_gen.php?filename=\1");
restart;
}
}
Maybe there are some better ways to solve this problem? I know that Varnish supports C in VCL, maybe it is better to check file existence using C-code?