# ============================================================
# Nginx 代理缓存配置示例
# ============================================================
#
# 功能说明:
# - 缓存后端响应
# - 防止缓存击穿（cache lock）
# - stale-while-revalidate 支持
#
# Lolly 对应配置:
# server:
#   proxy:
#     - path: "/api"
#       targets:
#         - url: "http://backend:8080"
#       cache:
#         enabled: true
#         max_age: 60s
#         cache_lock: true
#         stale_while_revalidate: 30s
# ============================================================

http {
    # 缓存区域定义
    # levels: 目录层级结构
    # keys_zone: 元数据缓存区
    # max_size: 最大磁盘空间
    # inactive: 未访问淘汰时间
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=100m inactive=60m use_temp_path=off;

    # 缓存键定义
    # 可基于 URI、参数、Header 等
    proxy_cache_key "$scheme$request_method$host$request_uri";

    server {
        listen 80;
        server_name cache.example.com;

        location /api {
            # 启用缓存
            # Lolly 对应: cache.enabled: true
            proxy_cache api_cache;

            # 缓存键（可选自定义）
            # proxy_cache_key "$request_uri$http_x_api_version";

            # 缓存有效期
            # Lolly 对应: cache.max_age: 60s
            proxy_cache_valid 200 60s;  # 成功响应缓存 60s
            proxy_cache_valid 301 302 10m;  # 重定向缓存 10m
            proxy_cache_valid 404 1m;  # 404 缓存 1m
            proxy_cache_valid any 5s;  # 其他响应缓存 5s

            # 缓存锁（防止缓存击穿）
            # Lolly 对应: cache.cache_lock: true
            proxy_cache_lock on;
            proxy_cache_lock_timeout 5s;  # 锁等待超时
            proxy_cache_lock_age 30s;  # 锁过期时间

            # stale-while-revalidate
            # 在后台刷新缓存时返回过期数据
            # Lolly 对应: cache.stale_while_revalidate: 30s
            proxy_cache_use_stale updating;  # 更新时使用过期缓存
            proxy_cache_use_stale error timeout;  # 错误时使用缓存
            proxy_cache_use_stale http_500 http_502 http_503 http_504;  # 后端错误时使用缓存

            # 缓存背景更新
            proxy_cache_background_update on;

            # 缓存状态头（调试用）
            add_header X-Cache-Status $upstream_cache_status;

            proxy_pass http://backend:8080;
        }

        # 禁用缓存的路径
        location /api/no-cache {
            proxy_cache off;

            proxy_pass http://backend:8080;
        }

        # 手动清除缓存（需要 ngx_cache_purge 模块）
        location ~ /purge(/.*) {
            allow 127.0.0.1;
            deny all;
            proxy_cache_purge api_cache "$scheme$request_method$host$1";
        }
    }
}

# 缓存状态值说明:
#
# $upstream_cache_status 可能的值:
# MISS: 未命中缓存，从后端获取
# HIT: 命中缓存
# STALE: 使用过期缓存（后端不可用）
# UPDATING: 使用过期缓存（正在后台更新）
# REVALIDATED: 缓存重新验证成功
# EXPIRED: 缓存过期
# BYPASS: 跳过缓存
#
# 缓存击穿防护:
#
# 1. cache_lock:
#    - 同一请求只有一个去后端
#    - 其他请求等待或返回过期缓存
#    - 防止大量请求同时打到后端
#
# 2. stale-while-revalidate:
#    - 缓存过期时返回旧数据
#    - 后台异步刷新缓存
#    - 用户不感知刷新延迟
#
# 3. 缓存预热:
#    - 预先请求热门内容
#    - 避免首次请求 MISS