# ============================================================ # 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 可热更新路由规则