# ============================================================ # Nginx content_by_lua 内容生成配置示例 # ============================================================ # # 功能说明: # - 使用 Lua 动态生成响应 # - JSON API 实现 # - 模板渲染 # # Lolly 对应配置: # 可通过 Lua 沙箱实现动态内容生成 # ============================================================ http { lua_shared_dict cache 10m; server { listen 80; server_name content-lua.example.com; # 动态 JSON API location /api/status { content_by_lua_block { local cjson = require "cjson.safe" -- 构建响应数据 local response = { status = "ok", timestamp = ngx.now(), server = ngx.var.hostname, workers = ngx.worker.count(), connections = ngx.var.connections_active, } -- 设置响应头 ngx.header["Content-Type"] = "application/json" ngx.header["Cache-Control"] = "no-cache" -- 输出 JSON ngx.say(cjson.encode(response)) } } # 缓存的 API 响应 location /api/cached { content_by_lua_block { local cjson = require "cjson.safe" local cache = ngx.shared.cache local cache_key = "api_data" local cached = cache:get(cache_key) if cached then ngx.header["X-Cache"] = "HIT" ngx.header["Content-Type"] = "application/json" ngx.say(cached) return end -- 模拟数据获取 local data = { items = { {id = 1, name = "Item 1"}, {id = 2, name = "Item 2"}, }, generated = ngx.now(), } local json = cjson.encode(data) cache:set(cache_key, json, 60) -- 缓存 60 秒 ngx.header["X-Cache"] = "MISS" ngx.header["Content-Type"] = "application/json" ngx.say(json) } } # 健康检查端点 location /health { content_by_lua_block { local health = { status = "healthy", checks = {} } -- 检查数据库连接(示例) local db_ok = true -- 实际应检查数据库 table.insert(health.checks, { name = "database", status = db_ok and "ok" or "error" }) -- 检查缓存 local cache = ngx.shared.cache table.insert(health.checks, { name = "cache", status = cache and "ok" or "error" }) ngx.header["Content-Type"] = "application/json" ngx.say(require("cjson.safe").encode(health)) } } # 表单处理 location /api/form { content_by_lua_block { local cjson = require "cjson.safe" -- 读取请求体 ngx.req.read_body() local body_data = ngx.req.get_body_data() if not body_data then ngx.status = 400 ngx.say(cjson.encode({error = "No body data"})) ngx.exit(400) end -- 解析 JSON local data = cjson.decode(body_data) if not data then ngx.status = 400 ngx.say(cjson.encode({error = "Invalid JSON"})) ngx.exit(400) end -- 处理数据 local response = { success = true, received = data, processed_at = ngx.now() } ngx.header["Content-Type"] = "application/json" ngx.say(cjson.encode(response)) } } } } # content_by_lua 说明: # # 1. 执行时机: # - 在 access 阶段之后 # - 用于生成响应内容 # - 替代 proxy_pass 或静态文件 # # 2. 常用操作: # - ngx.say(): 输出内容 # - ngx.print(): 输出内容(无换行) # - ngx.exit(): 结束请求 # - ngx.header[]: 设置响应头 # # 3. JSON 处理: # - cjson.encode(table): 表转 JSON # - cjson.decode(string): JSON 转表 # - cjson.safe 版本不会抛异常 # # 4. 请求体处理: # - ngx.req.read_body(): 读取请求体 # - ngx.req.get_body_data(): 获取请求体数据 # - ngx.req.get_post_args(): 获取表单参数 # # 5. 性能考虑: # - 使用共享字典缓存 # - 避免阻塞操作 # - 使用 cosocket 进行外部调用