Nginx反向代理缓存301重定向而非目标资源如何调整配置?
问题根因
你当前配置中的Nginx仅作为简单的反向透传代理,收到上游返回的301响应后会直接透传给客户端,不会主动跟随重定向去请求AWS端的最终资源,因此缓存的只有301响应本身,自然达不到缓存大体积pdb文件的效果。
解决方案
根据你的环境可以选择以下两种实现方案:
方案1:使用第三方重定向跟随模块(推荐,逻辑简单)
先给Nginx编译安装ngx_http_follow_redirects模块,之后调整location配置如下:
location / { proxy_pass http://server.org/; # 开启跟随重定向,最大跟随次数设为2避免重定向循环 proxy_follow_redirects on; proxy_follow_redirects_max 2; proxy_cache one; proxy_http_version 1.1; proxy_intercept_errors on; proxy_cache_key $scheme$request_uri; # 仅缓存200状态的最终资源,排除301响应的缓存 proxy_cache_valid 200 24h; proxy_redirect default; }
该方案下Nginx会自动识别上游301响应中的Location字段,主动请求对应地址获取最终资源,返回给客户端的同时缓存资源内容。
方案2:原生Nginx实现(无需额外模块)
利用error_page捕获301响应,再发起二次代理请求到AWS资源地址,完整配置参考:
user nginx; worker_processes 1; events { worker_connections 10240; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 4096; include /etc/nginx/mime.types; default_type application/octet-stream; proxy_cache_path /var/cache/nginx keys_zone=one:10m use_temp_path=off; # 新增变量存储重定向目标地址 map $sent_http_location $redirect_target { ~^(?<target>.*)$ $target; } server { listen 80; listen [::]:80; server_name _; root /usr/share/nginx/html; include /etc/nginx/default.d/*.conf; # 处理原始请求的location location / { proxy_pass http://server.org/; proxy_intercept_errors on; # 捕获301响应,内部转发到重定向处理location error_page 301 = @fetch_redirect_target; } # 处理重定向资源请求的location location @fetch_redirect_target { proxy_pass $redirect_target; proxy_cache one; proxy_cache_key $scheme$request_uri; # 仅缓存200状态的最终资源 proxy_cache_valid 200 24h; proxy_http_version 1.1; # 配置DNS解析器,用于解析AWS服务域名,可替换为你内网的DNS地址 resolver 8.8.8.8 valid=300s; resolver_timeout 10s; } } }
额外优化建议
- 针对大体积pdb文件可添加
proxy_max_temp_file_size 0配置,避免大文件写入临时文件拖慢性能 - 可新增
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504配置,缓存失效时优先返回旧内容,提升可用性
内容的提问来源于stack exchange,提问作者Marc-Antoine Caron
相关产品推荐
相关产品推荐

