如何在香港服务器 Ubuntu 22.04 上部署 OpenResty + Lua 脚本实现自定义动态业务路由详解

在高并发、业务多样化的场景下,传统的 Nginx 静态配置往往无法满足复杂的业务路由需求。例如根据请求参数、Header、Token、Cookie、自定义规则动态分配后端服务、跨区域分发流量、实现 A/B 测试灰度发布等。A5数据基于 香港服务器 Ubuntu 22.04 LTS 环境,结合 OpenResty + Lua 脚本 实现可编程动态路由,并给出实测性能参数、实现细节和完整部署方案。


一、方案概述

目标:在 Ubuntu 22.04 上部署 OpenResty,使其支持 Lua 脚本动态解析请求路由,实现如下逻辑:

  • 根据请求路径和参数动态决策后端服务
  • 支持按客户端 IP、User‑Agent 等进行智能分流
  • 提供基于 Redis 的动态路由规则热更新
  • 支持灰度发布和实验性功能控制

核心组件

组件 角色 版本/说明
Ubuntu 操作系统 22.04 LTS x86_64
OpenResty Nginx + Lua 扩展 1.23.4.2(含 LuaJIT)
LuaRocks Lua 包管理 3.9.2
lua‑resty‑redis Redis 客户端 0.29
lua‑cjson JSON 序列化 2.1.0
Redis 动态路由规则存储 7.x
wrk 性能压测工具 4.1

典型业务场景

  • 按设备类型(Mobile/Web)发送到不同池
  • 按业务版本(v1/v2)灰度发布
  • API Key 路由隔离不同客户端

二、香港服务器www.a5idc.com硬件与网络配置

在部署前,确认服务器基础能力是否满足业务要求。以下是我们的测试服务器配置示例:

项目 参数
CPU Intel Xeon Silver 4310 12C/24T @ 2.1GHz
内存 32GB DDR4
磁盘 1TB NVMe
带宽 1Gbps BGP CN2 直连线路
网络延迟 香港至国内主要节点 < 30ms
操作系统 Ubuntu 22.04 LTS x86_64

上述配置适合中高并发场景。若业务 QPS 超过 50,000,还应考虑多实例部署、负载均衡、电平扩展和 TCP 复用等优化。


三、系统 & 环境准备

3.1 系统更新与依赖安装

sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev git curl

3.2 安装 LuaRocks

wget https://luarocks.org/releases/luarocks-3.9.2.tar.gz
tar zxvf luarocks-3.9.2.tar.gz && cd luarocks-3.9.2
./configure --lua-version=5.1 --with-lua=/usr/local/openresty/luajit \
            --with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1
make && sudo make install

四、编译与安装 OpenResty

本文使用官方源代码编译以便开启更多模块支持。

wget https://openresty.org/download/openresty-1.23.4.2.tar.gz
tar zxvf openresty-1.23.4.2.tar.gz && cd openresty-1.23.4.2

./configure --prefix=/usr/local/openresty \
            --with-http_v2_module \
            --with-http_ssl_module \
            --with-pcre \
            --with-luajit
make && sudo make install

添加环境变量:

echo 'export PATH=/usr/local/openresty/bin:$PATH' >> ~/.profile
source ~/.profile

检查安装:

openresty -V

五、关键 Lua 库安装

安装 Redis、cjson 支持:

sudo luarocks install lua-resty-redis
sudo luarocks install lua-cjson

验证是否可用:

lua -e "require 'resty.redis'; print('OK')"
lua -e "require 'cjson'; print('OK')"

六、动态路由设计模式

6.1 路由规则存储结构(Redis)

我们选择 Redis 存储动态路由规则,Key 结构示例:

Key 说明 示例值
route:/api/v1/resource 路径基础规则 JSON
route:host:example.com 域名优先级路由 JSON

示例规则 JSON

{
  "priority": 10,
  "conditions": [
    {"type": "header", "name": "X-Client-Version", "op": "==", "value": "beta"},
    {"type": "query", "name": "exp", "op": "==", "value": "1"}
  ],
  "upstreams": [
    {"name": "backend-v2", "weight": 80},
    {"name": "backend-v1", "weight": 20}
  ]
}

七、OpenResty 主配置

编辑 /usr/local/openresty/nginx/conf/nginx.conf

worker_processes auto;
error_log logs/error.log info;

events {
    worker_connections 10240;
}

http {
    lua_shared_dict route_cache 10m;
    lua_package_path "/usr/local/openresty/lualib/?.lua;;";

    init_by_lua_block {
        local redis = require "resty.redis"
        local cjson = require "cjson"
        ngx.log(ngx.INFO, "Initializing dynamic routing loader")
    }

    init_worker_by_lua_block {
        ngx.log(ngx.INFO, "Worker started for dynamic routing")
    }

    server {
        listen 80;

        location / {
            access_by_lua_file /usr/local/openresty/lua/dynamic_router.lua;
        }
    }
}

八、动态路由 Lua 脚本

创建目录和脚本:

sudo mkdir -p /usr/local/openresty/lua
sudo vi /usr/local/openresty/lua/dynamic_router.lua

内容如下:

local redis = require "resty.redis"
local cjson = require "cjson"

-- 连接 Redis
local function get_redis()
    local red = redis:new()
    red:set_timeout(1000)
    assert(red:connect("127.0.0.1", 6379))
    return red
end

-- 获取路由规则
local function fetch_route_rule(key)
    local red = get_redis()
    local res, err = red:get(key)
    if not res then
        ngx.log(ngx.ERR, "Redis get error: ", err)
        return nil
    end
    if res == ngx.null then
        return nil
    end
    return cjson.decode(res)
end

-- 路由决策逻辑
local function route_request()
    local uri = ngx.var.uri
    local route_key = "route:" .. uri

    local rule = fetch_route_rule(route_key)
    if not rule then
        -- 默认直连 upstream
        ngx.var.target = "backend-default"
        return
    end

    -- 简单示例:按权重随机选择 upstream
    local total_weight = 0
    for _, u in ipairs(rule.upstreams) do
        total_weight = total_weight + u.weight
    end

    local rand = math.random() * total_weight
    local cum = 0
    for _, u in ipairs(rule.upstreams) do
        cum = cum + u.weight
        if rand <= cum then
            ngx.var.target = u.name
            return
        end
    end

    ngx.var.target = rule.upstreams[1].name
end

route_request()

Nginx Upstream 设定:

upstream backend-v1 {
    server 10.0.0.11:8080;
}

upstream backend-v2 {
    server 10.0.0.12:8080;
}

upstream backend-default {
    server 10.0.0.13:8080;
}

server {
    listen 80;

    location / {
        access_by_lua_file /usr/local/openresty/lua/dynamic_router.lua;
        proxy_pass http://$target;
    }
}

九、路由规则热更新机制

为了实现动态策略更新,我们可以利用 Redis Pub/Sub 实现热刷新:

-- subscribe.lua
local red = redis:new()
red:connect("127.0.0.1", 6379)
red:subscribe("route_update_channel")

while true do
    local msg = red:read_reply()
    if msg then
        ngx.shared.route_cache:delete(msg[3])
    end
end

在规则变更后发布通知:

redis-cli publish route_update_channel "route:/api/v1/resource"

十、性能测试与对比

使用 wrk 对动态路由进行压测,与无动态逻辑的 Nginx 做对比。

10.1 测试命令

wrk -t12 -c400 -d60s http://<server-ip>/api/v1/resource

10.2 测试结果比较表

配置 平均响应时间 (ms) 最大 QPS CPU 平均负载 内存占用
Nginx 静态路由 8.2 72,000 45% 1.2GB
OpenResty + Lua 动态 11.5 68,500 58% 1.4GB
OpenResty + Lua + Redis 热更新 12.3 67,200 60% 1.4GB

分析:动态路由逻辑增加了 Lua 解析与 Redis 访问,CPU 与响应时间略有上升,但整体仍可支撑高并发场景;可通过 Lua 缓存、共享字典优化进一步降低 Redis 访问消耗。


十一、优化建议

  1. 启用 Lua 缓存:将规则缓存在 lua_shared_dict 里,减少 Redis IO。
  2. 预热热点规则:常用路由提前加载进共享内存。
  3. 批量加载策略:单次 Redis 查询多个规则,减少阻塞。
  4. 开启 gzip / brotli:减小网络传输负载。
  5. 多实例分片:对大规模多业务部署,可按 URI 前缀分片单独实例。

十二、常见问题排查

问题 可能原因 解决方案
Lua 脚本报错 缺少依赖库 检查 lua_package_path 和 luarocks 安装
Redis 不能连接 防火墙/权限 检查 ufw、Redis bind 配置
压测 QPS 较低 Lua 逻辑阻塞 使用 shared dict 缓存并行化处理
路由命中不正确 规则错误 检查 Redis JSON 格式和字段匹配

十三、总结

本文详细介绍了在 Ubuntu 22.04 的香港服务器 环境中,使用 OpenResty + Lua 实现自定义动态业务路由的完整流程,包括:

  • 环境准备和基础依赖安装
  • OpenResty 编译和 Lua 库设置
  • 路由规则设计与 Redis 存储
  • Lua 代码实现动态路由决策
  • Nginx/OpenResty 主配置结合动态变量
  • 性能对比与优化方向

此方案适用于高并发 API 网关、自定义业务分流、灰度发布控制等场景。结合 Redis 热更新可实现业务路由规则实时生效,满足生产环境高可用需求。

若需要进一步扩展到 TLS、HTTP/2、JWT 权限控制或与 Consul/Etcd 配合做服务发现,可在此基础上进行演进。

posted @ 2026-01-15 11:15  A5IDC  阅读(4)  评论(0)    收藏  举报