- config: 反向代理、缓存、负载均衡、安全、SSL 等配置模板 - lua: API 网关、认证、动态路由、限流、WebSocket 等脚本示例 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
179 lines
5.1 KiB
Nginx Configuration File
179 lines
5.1 KiB
Nginx Configuration File
# ============================================================
|
|
# Nginx 动态路由配置示例
|
|
# ============================================================
|
|
#
|
|
# 功能说明:
|
|
# - 基于路径和请求头的动态路由分发
|
|
# - 灰度发布支持
|
|
# - 多后端服务选择
|
|
#
|
|
# Lolly 对应配置:
|
|
# lolly 内置 Lua 沙箱支持,可通过 lua_scripts 嵌入路由逻辑
|
|
# 相关文档: docs/lua-nginx-module/08-balancer.md
|
|
# ============================================================
|
|
|
|
http {
|
|
# 共享字典: 存储路由配置
|
|
lua_shared_dict router_config 5m;
|
|
|
|
# Lua 模块路径
|
|
lua_package_path "/usr/local/nginx/lua/?.lua;;";
|
|
|
|
# 初始化路由配置
|
|
init_by_lua_block {
|
|
local router_config = ngx.shared.router_config
|
|
local cjson = require "cjson.safe"
|
|
|
|
-- 定义路由规则
|
|
local rules = {
|
|
-- 路径路由
|
|
path = {
|
|
{ prefix = "/api/v2", upstream = "api_v2" },
|
|
{ prefix = "/api", upstream = "api_default" },
|
|
{ prefix = "/static", upstream = "static_server" },
|
|
{ prefix = "/ws", upstream = "websocket_server" },
|
|
},
|
|
-- 默认上游
|
|
default = "web_default",
|
|
}
|
|
|
|
router_config:set("rules", cjson.encode(rules))
|
|
|
|
ngx.log(ngx.INFO, "Dynamic routing initialized")
|
|
}
|
|
|
|
# ---- 上游服务定义 ----
|
|
|
|
upstream api_v2 {
|
|
server 10.0.1.10:8080;
|
|
server 10.0.1.11:8080;
|
|
}
|
|
|
|
upstream api_default {
|
|
server 10.0.2.10:8080;
|
|
server 10.0.2.11:8080;
|
|
}
|
|
|
|
upstream api_v2_canary {
|
|
server 10.0.3.10:8080;
|
|
}
|
|
|
|
upstream static_server {
|
|
server 10.0.4.10:80;
|
|
}
|
|
|
|
upstream websocket_server {
|
|
server 10.0.5.10:9000;
|
|
}
|
|
|
|
upstream web_default {
|
|
server 10.0.6.10:8080;
|
|
server 10.0.6.11:8080;
|
|
}
|
|
|
|
# ---- 主服务 ----
|
|
|
|
server {
|
|
listen 80;
|
|
server_name router.example.com;
|
|
|
|
# 动态路由分发
|
|
location / {
|
|
set $target_upstream "";
|
|
|
|
access_by_lua_block {
|
|
local router = require "router"
|
|
local upstream_name = router.select(ngx)
|
|
|
|
if not upstream_name then
|
|
ngx.log(ngx.ERR, "No matching upstream found")
|
|
return ngx.exit(503)
|
|
end
|
|
|
|
-- 将选中的上游保存到变量
|
|
ngx.var.target_upstream = upstream_name
|
|
}
|
|
|
|
proxy_pass http://$target_upstream;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# 添加路由调试头(可选)
|
|
add_header X-Selected-Upstream $target_upstream always;
|
|
}
|
|
|
|
# WebSocket 专用 location
|
|
location /ws {
|
|
set $target_upstream "websocket_server";
|
|
|
|
proxy_pass http://$target_upstream;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
# 路由管理接口(仅内网访问)
|
|
location /admin/routes {
|
|
allow 127.0.0.1;
|
|
deny all;
|
|
|
|
content_by_lua_block {
|
|
local router = require "router"
|
|
local cjson = require "cjson.safe"
|
|
|
|
local method = ngx.req.get_method()
|
|
|
|
if method == "GET" then
|
|
local rules = router.get_rules()
|
|
ngx.header["Content-Type"] = "application/json"
|
|
ngx.say(cjson.encode(rules))
|
|
|
|
elseif method == "POST" then
|
|
ngx.req.read_body()
|
|
local body = ngx.req.get_body_data()
|
|
local ok, err = router.update_rules(body)
|
|
|
|
if not ok then
|
|
ngx.status = 400
|
|
ngx.say(cjson.encode({ error = err }))
|
|
ngx.exit(400)
|
|
end
|
|
|
|
ngx.say(cjson.encode({ success = true }))
|
|
else
|
|
ngx.status = 405
|
|
ngx.exit(405)
|
|
end
|
|
}
|
|
}
|
|
|
|
# 健康检查端点
|
|
location /health {
|
|
access_log off;
|
|
return 200 "ok";
|
|
}
|
|
}
|
|
}
|
|
|
|
# 路由配置说明:
|
|
#
|
|
# 1. upstream 定义:
|
|
# - api_v2: API v2 服务
|
|
# - api_default: API 默认版本
|
|
# - api_v2_canary: API v2 灰度实例
|
|
# - static_server: 静态资源服务
|
|
# - websocket_server: WebSocket 服务
|
|
# - web_default: 默认 Web 服务
|
|
#
|
|
# 2. 路由选择流程:
|
|
# a) 检查 X-Service 请求头 -> 直接使用指定 upstream
|
|
# b) 检查 X-Canary 头 -> 选择灰度 upstream
|
|
# c) 按路径前缀匹配 -> 选择对应 upstream
|
|
# d) 回退到默认 upstream
|
|
#
|
|
# 3. 动态更新:
|
|
# POST /admin/routes 可热更新路由规则
|