lolly/docs/config/lua/content-by-lua.conf
xfy 6543422281 docs: 添加 Nginx 配置和 Lua 脚本示例文档
- config: 反向代理、缓存、负载均衡、安全、SSL 等配置模板
- lua: API 网关、认证、动态路由、限流、WebSocket 等脚本示例

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 17:59:22 +08:00

168 lines
4.9 KiB
Plaintext

# ============================================================
# 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 进行外部调用