# ============================================================ # Nginx Lua Caching Configuration # ============================================================ # # 功能说明: # - 使用 Lua 共享字典缓存响应 # - 支持 TTL 过期和手动失效 # - X-Cache 头标识缓存命中状态 # # 使用方式: # lua_shared_dict response_cache 10m; # content_by_lua_file /path/to/cache_handler.lua; # ============================================================ http { # 共享字典定义 lua_shared_dict response_cache 10m; # 初始化 Lua 模块路径 lua_package_path "/path/to/lua/?.lua;;"; init_by_lua_block { -- 全局配置 CACHE_DEFAULT_TTL = 60 } server { listen 80; server_name cache.example.com; # ---------- 缓存读取示例 ---------- location /api/data { set $cache_key "api_data:$request_uri"; content_by_lua_block { local handler = require "cache_handler" local cache = ngx.shared.response_cache local key = ngx.var.cache_key local ttl = tonumber(ngx.var.arg_ttl) or CACHE_DEFAULT_TTL -- 尝试缓存命中 local cached = cache:get(key) if cached then ngx.header["X-Cache"] = "HIT" ngx.header["Content-Type"] = "application/json" ngx.header["X-Cache-TTL"] = tostring(cache:ttl(key)) ngx.say(cached) return end -- 缓存未命中,生成数据 local data = { message = "fresh data", timestamp = ngx.now(), uri = ngx.var.request_uri, } local cjson = require "cjson.safe" local json = cjson.encode(data) -- 写入缓存 local ok, err, forcible = cache:set(key, json, ttl) if not ok then ngx.log(ngx.ERR, "cache set failed: ", err) end if forcible then ngx.log(ngx.WARN, "cache LRU eviction triggered") end ngx.header["X-Cache"] = "MISS" ngx.header["Content-Type"] = "application/json" ngx.say(json) } } # ---------- 使用外部 Lua 文件 ---------- location /api/handler { set $cache_key "handler:$request_uri"; set $cache_ttl 120; content_by_lua_file /path/to/lua/cache_handler.lua; } # ---------- 缓存失效:清除指定 key ---------- location /cache/purge { content_by_lua_block { if ngx.req.get_method() ~= "POST" then ngx.status = 405 ngx.say('{"error": "method not allowed"}') return end ngx.req.read_body() local body = ngx.req.get_body_data() if not body then ngx.status = 400 ngx.say('{"error": "missing request body"}') return end local cjson = require "cjson.safe" local data = cjson.decode(body) if not data or not data.key then ngx.status = 400 ngx.say('{"error": "missing key field"}') return end local cache = ngx.shared.response_cache cache:delete(data.key) ngx.header["Content-Type"] = "application/json" ngx.say(cjson.encode({success = true, purged = data.key})) } } # ---------- 缓存失效:清除全部 ---------- location /cache/purge_all { # 仅允许本地访问 allow 127.0.0.1; deny all; content_by_lua_block { if ngx.req.get_method() ~= "POST" then ngx.status = 405 ngx.say('{"error": "method not allowed"}') return end local cache = ngx.shared.response_cache local count = cache:flush_all() -- flush_all 标记所有 key 过期,flush_expired 实际清理 cache:flush_expired(0) ngx.header["Content-Type"] = "application/json" ngx.say('{"success": true, "action": "all keys invalidated"}') } } # ---------- 缓存统计 ---------- location /cache/stats { content_by_lua_block { local cache = ngx.shared.response_cache local keys = cache:get_keys(0) -- 0 = 不过滤过期 key local cjson = require "cjson.safe" local stats = { capacity = cache:capacity(), free_space = cache:free_space(), key_count = #keys, } ngx.header["Content-Type"] = "application/json" ngx.say(cjson.encode(stats)) } } } }