We are using apache2.2 as a front-end server with application servers as reverse proxies behind apache.
We are using
mod_cache for some images and enabled it like this:
<IfModule mod_disk_cache.c> CacheEnable disk / CacheRoot /var/cache/apache2/mod_disk_cache CacheIgnoreCacheControl On CacheMaxFileSize 2500000 CacheIgnoreURLSessionIdentifiers jsessionid CacheIgnoreHeaders Set-Cookie </IfModule>
The image urls vary completely and have no common start pattern, but they all end in ".png". Thats why we used the root in
If not served from the cache, the request is forwarded to an application server via reverse proxy. So far so good, cache is working fine.
But I really only need to cache all image request ending in ".png". My above configuration still works as my application server send an appropriate Cache-Control: no-cache header on the way back to apache. So most pages send a no-cache header back and they get not cached at all. My ".png" responses doesn't send a Cache-Control header so apache is only going to cache all urls with ".png". Fine.
But when a new request enters apache, apache does not know that only .png requests should be considered, so every request is checking a file on disk (recorded with
strace -e trace=file -p pid):
[pid 19063] open("/var/cache/apache2/mod_disk_cache/zK/q8/Kd/g6OIv@woJRC_ba_A.header", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
I don't want to have apache going to disk every request, as the majority of requests are not cached at all. And we have up to 10.000 request/s at peak time. Sometimes our read IO wait spikes. It is not getting really slow, but we try to tweak it for better performance.
In apache 2.4 you can say:
<LocationMatch .png$> CacheEnable disk </LocationMatch>
This is not possible in 2.2 and as I see no backports for debian I am not going to upgrade.
So I tried to tweak apache2.2 to follow my rules:
<IfModule mod_disk_cache.c> SetEnvIf Request_URI "\.png$" image RequestHeader unset Cache-Control RequestHeader append Cache-Control no-cache env=!image CacheEnable disk / CacheRoot /var/cache/apache2/mod_disk_cache #CacheIgnoreCacheControl on CacheMaxFileSize 2500000 CacheIgnoreURLSessionIdentifiers jsessionid CacheIgnoreHeaders Set-Cookie </IfModule>
The idea is to let apache decide to serve request from cache based on Cache-control header (CacheIgnoreCacheControl default to off). And before simply set a RequestHeader based on the request. If it is not an image request, set a Cache-control header, so it should bypass the cache at all.
This does not work, I guess because of late processing of RequestHeader directive, see https://httpd.apache.org/docs/2.2/mod/mod_headers.html#early
I can't add early processing as "early" keyword can't be used together with a conditional "env=!image"
I can't change the url requesting the images and I know there are of course other solutions. But I am only interested in configuring apache2.2 to reach my goal.
Does anybody has an idea how to achieve my goal?