如何在香港服务器 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 访问消耗。
十一、优化建议
- 启用 Lua 缓存:将规则缓存在
lua_shared_dict里,减少 Redis IO。 - 预热热点规则:常用路由提前加载进共享内存。
- 批量加载策略:单次 Redis 查询多个规则,减少阻塞。
- 开启 gzip / brotli:减小网络传输负载。
- 多实例分片:对大规模多业务部署,可按 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 配合做服务发现,可在此基础上进行演进。

浙公网安备 33010602011771号