我有一个非常简单的代理配置:
http {
proxy_cache_path /var/www/cache levels=1:2 keys_zone=s3-images-cache:50m inactive=1M max_size=1000m;
proxy_temp_path /var/www/cache/tmp;
server {
listen 80;
server_name images.example.com;
location / {
proxy_cache s3-images-cache;
proxy_cache_key $scheme$proxy_host$uri$is_args$args;
proxy_cache_bypass $http_purge_cache;
proxy_cache_valid any 1y;
proxy_pass http://images-example.s3.amazonaws.com;
add_header X-Cache $upstream_cache_status;
proxy_intercept_errors on;
error_page 404 = @no_image;
}
location @no_image {
return 403;
}
}
}
现在关注我:
- 让我们请求/image.jpg。
- 请求已发送至/image.jpg 的代理(尚不存在)。
- 后端响应 404。
- “proxy_intercept_errors on”启动并且调用“error_page 404 = @no_image”。
- Nginx 返回 403。
- 对同一张图片进行另一个请求,并查看是否设置了“X-Cache: HIT”。我们显然正在访问代理缓存。
但是,如果我们此时检查 /var/www/cache/ 文件夹,我们将看到没有为该请求创建缓存项。那么这是否意味着 Nginx 在内存中保留了缓存,而忘记写入文件了?
- 让我们将/image.jpg 上传到后端。
- 现在对该图像执行“PURGE-CACHE: 1”请求。我们看到现在我们得到了图像,而不是带有“X-Cache: BYPASS”标头的 403。很好。
如果我们检查 /var/www/cache/,我们会看到缓存文件现在终于为该请求创建了。查看缓存文件,我们发现它是我们的图像。
- 现在问题来了:让我们再次使用普通的 GET 请求来请求 /image.jpg。我们应该获取新上传的图片吧?
- Nginx 返回 403 错误,并显示“X-Cache: HIT”。为什么?它似乎命中了缓存,但返回的内容不是 /var/www/cache 文件夹中的内容?为什么?
我对此的唯一解释是,似乎 Nginx 正在将响应缓存在内存中,并且当我们在代理响应中使用自定义 error_page 时遇到错误时不会写入文件。此外,当使用 proxy_cache_bypass 时,它不会覆盖内存缓存,因此对同一项目的后续请求将使用存储在内存中的旧缓存,而不是在缓存文件夹中创建的新缓存。
有人能告诉我我是否做错了什么或者这真的是一个错误吗?我花了 3 天时间解决这个问题。
更新:后端返回您期望从 S3 在 200 和 404 响应中得到的正常标头集:
404
Connection:close
Content-Type:application/xml
Date:Fri, 20 Nov 2015 07:41:39 GMT
Server:AmazonS3
Transfer-Encoding:chunked
x-amz-id-2:bH8L/1dOVGShsGJdZZ/zS/X6UkHS+KMAxDxnPvOkIalpPphFJXr9zZ1RiV6L2a13NXoZ3QdCOeE=
x-amz-request-id:D66FDBFAA9643252
200
Accept-Ranges:bytes
Connection:keep-alive
Content-Length:10533
Content-Type:image/jpeg
Date:Fri, 20 Nov 2015 07:47:12 GMT
ETag:"061b4dae0b2bbdf4a4fa212951f4ba79"
Last-Modified:Wed, 11 Nov 2015 14:29:09 GMT
Server:AmazonS3
x-amz-id-2:qsSmH/gkvql2jnj67p0vguZBXQJHfS+Yk70llBaDvbgH0xSCbvj9G9JlKn5WhWTdty0+JzApN7k=
x-amz-request-id:8CF04EA869190E63