Nginx proxy cache始终返回x-cache-status: MISS,缓存失效求助
Let’s break down why your Nginx caching for https://p.rmiao.top/proxy/bing/HPImageArchive.aspx?format=js&idx=0&n=2 isn’t working, even after ignoring Cache-Control and Set-Cookie headers. I’ve debugged dozens of similar issues, so let’s walk through targeted checks step by step.
1. Validate Your Core Cache Configuration
First, double-check that your foundational caching setup is correct—this is where most folks stumble:
- You must define a
proxy_cache_pathin yourhttpblock to tell Nginx where to store cache files. If this is missing, caching won’t work at all:http { # Example: Creates a cache zone named "bing_cache" with 10MB metadata storage, max 10GB total cache, expires after 72h of inactivity proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=bing_cache:10m max_size=10g inactive=72h use_temp_path=off; } - Make sure you’ve enabled caching in your target
locationblock withproxy_cache bing_cache;(matching the zone name fromproxy_cache_path). - Watch out for accidental
proxy_no_cacheorproxy_cache_bypassrules that always evaluate totrue—these will completely bypass the cache. For example, if you haveproxy_no_cache $http_pragma;, check if thePragmaheader is being sent with every request to your proxy URL.
2. Fix How You Override Upstream Cache Headers
Ignoring Cache-Control and Set-Cookie isn’t enough on its own—you need to explicitly tell Nginx how long to cache the response. If you don’t set a TTL, Nginx won’t know when to keep the cache entry. Update your location block like this:
location /proxy/bing/ { proxy_cache bing_cache; # Ignore upstream headers that block caching proxy_ignore_headers Cache-Control Set-Cookie Expires; # Set explicit cache durations for successful responses proxy_cache_valid 200 4h; # Fallback cache duration for non-200 responses (optional but useful) proxy_cache_valid any 1h; # Optional: Tell client browsers to cache the response too add_header Cache-Control "public, max-age=14400"; # Don't forget your proxy_pass directive to Bing proxy_pass https://www.bing.com/; proxy_pass_request_uri on; }
3. Check for Hidden Upstream Headers Blocking Caching
Even with proxy_ignore_headers, some upstream headers can still interfere. Use curl to fetch the raw Bing endpoint response and look for:
Vary: *: This tells Nginx the response varies for every request, so it won’t cache by default. Fix this by either ignoring theVaryheader or adding varying values to your cache key.X-Cacheor other custom headers that might signal the upstream doesn’t allow caching.
Run this command to inspect upstream headers:
curl -I "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=2"
4. Ensure Your Cache Key Is Consistent
Nginx’s default cache key ($scheme$proxy_host$request_uri) works for most cases, but subtle request differences (like reordered query params or hidden headers) can create unique keys for identical requests. Explicitly define a cache key to force consistency:
proxy_cache_key "$scheme$host$request_uri";
You can also verify if cache files are being created by checking the directory you set in proxy_cache_path (e.g., /var/cache/nginx). If you see files there after making requests, the cache is being written—if not, Nginx is skipping caching entirely.
5. Enable Cache Logging for Debugging
Add cache-specific logging to get concrete data on why requests aren’t hitting the cache. Update your http or server block:
log_format cache_log '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'cache_status=$upstream_cache_status'; access_log /var/log/nginx/cache_access.log cache_log;
The $upstream_cache_status value will tell you exactly what’s happening:
HIT: Request served from cache (success!)MISS: Request wasn’t in cache (should be cached after first hit)BYPASS: Cache was bypassed due to your configurationEXPIRED: Cache entry expired (adjustproxy_cache_validif needed)
Check the logs in real-time with:
tail -f /var/log/nginx/cache_access.log
6. Verify Your Proxy Pass Setup
Make sure your proxy_pass directive isn’t mangling the request. For example, if you’re using proxy_pass https://www.bing.com/HPImageArchive.aspx;, you might be stripping the query string accidentally. Use proxy_pass_request_uri on; to preserve the full request path and params, as shown in step 2.
内容的提问来源于stack exchange,提问作者Ryan Miao




