1. 高性能 API 网关架构设计思路
在当今互联网服务架构中,API 网关作为流量入口和业务边界的核心组件,其性能表现直接影响整个系统的稳定性和用户体验。基于 Nginx 和 Lua 的组合方案之所以成为众多企业的首选,主要源于以下几个关键设计考量:
1.1 技术选型优势分析
OpenResty 作为 Nginx 的增强版本,集成了 LuaJIT 虚拟机,使得我们能够在 Nginx 的各个处理阶段嵌入 Lua 脚本。这种架构带来了三个显著优势:
- 性能卓越:LuaJIT 的执行效率接近 C 语言,避免了传统动态语言在网关层的性能瓶颈
- 开发效率高:Lua 语法简洁,配合丰富的 lua-resty 生态库,可以快速实现复杂业务逻辑
- 资源消耗低:单机即可支撑十万级并发,相比 Java/Go 等方案节省 60% 以上的服务器资源
1.2 核心功能模块设计
一个完整的 API 网关需要实现的功能矩阵包括:
plaintext复制认证鉴权 → 流量控制 → 请求转发 → 响应处理 → 监控告警
↑ ↑ ↑ ↑ ↑
JWT验证 速率限制 负载均衡 数据转换 指标采集
OAuth2.0 熔断降级 路径重写 缓存处理 日志追踪
1.3 性能指标分解
要达到生产级的高性能要求,我们需要针对以下指标进行专项优化:
- 连接处理能力:通过调整内核参数和 Nginx 配置,确保能维持 10 万+的 TCP 长连接
- 请求处理吞吐:Lua 脚本执行时间控制在 2ms 内,QPS 达到 3 万以上
- 资源利用率:CPU 负载均衡,避免单个 worker 进程过载
2. 环境准备与系统调优
2.1 硬件配置建议
对于百万级日活的 API 服务,推荐以下硬件配置作为基准线:
| 组件 | 推荐规格 | 性能影响说明 |
|---|---|---|
| CPU | 16核 Intel Xeon Silver | 每个 worker 进程需要 1-2 个物理核 |
| 内存 | 32GB DDR4 ECC | 共享字典缓存和连接状态存储 |
| 网络 | 10Gbps 以太网卡 | 避免网络成为瓶颈 |
| 存储 | NVMe SSD 500GB | 系统日志和临时文件存储 |
实际部署时建议进行容量规划:每 1万 QPS 需要约 2个CPU核心和 4GB 内存
2.2 操作系统优化
Rocky Linux 8.6 作为 RHEL 的兼容发行版,需要进行以下内核参数调整:
/etc/sysctl.d/99-nginx.conf
bash复制# 连接队列优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 端口范围扩展
net.ipv4.ip_local_port_range = 1024 65535
# TCP 协议优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
# 内存分配策略
vm.swappiness = 10
vm.overcommit_memory = 1
应用配置并验证:
bash复制sudo sysctl --system
sysctl -a | grep tcp_max_syn
关键参数解释:
tcp_tw_reuse:允许重用 TIME-WAIT 状态的 socket,缓解高并发下的端口耗尽问题overcommit_memory:防止因内存不足导致 OOM killer 误杀 Nginx 进程
3. OpenResty 部署与验证
3.1 安装最佳实践
通过官方仓库安装 OpenResty 能确保获得稳定支持:
bash复制# 添加仓库配置
cat <<EOF | sudo tee /etc/yum.repos.d/openresty.repo
[openresty]
name=OpenResty Repository
baseurl=https://openresty.org/package/rocky/\$releasever/\$basearch/
gpgcheck=1
gpgkey=https://openresty.org/package/pubkey.gpg
enabled=1
EOF
# 安装主程序
sudo dnf install openresty openresty-resty -y
# 验证安装
openresty -v
nginx -V 2>&1 | grep lua
3.2 目录结构规划
建议采用以下目录结构管理配置和脚本:
code复制/etc/openresty/
├── nginx/
│ ├── conf/ # 主配置目录
│ ├── logs/ # 日志文件
│ └── sites-enabled/ # 虚拟主机配置
├── lua/ # Lua 脚本
│ ├── lib/ # 第三方库
│ └── modules/ # 业务模块
└── certs/ # SSL 证书
4. Nginx 核心配置解析
4.1 主配置文件优化
/usr/local/openresty/nginx/conf/nginx.conf
nginx复制worker_processes auto;
worker_rlimit_nofile 200000;
events {
worker_connections 32768;
multi_accept on;
use epoll;
}
http {
lua_package_path "/etc/openresty/lua/?.lua;/usr/local/openresty/lualib/?.lua;;";
lua_shared_dict rate_limit 50m; # 限流计数器
lua_shared_dict api_keys 10m; # API密钥存储
init_by_lua_block {
require "resty.core"
collectgarbage("collect")
}
server {
listen 80 reuseport backlog=65535;
location /api {
access_by_lua_block {
local auth = require "modules.auth"
auth.check()
}
}
}
}
关键配置说明:
reuseport:启用端口复用,提升连接处理性能lua_shared_dict:定义共享内存区域,用于跨 worker 的数据交换init_by_lua_block:在 Nginx 启动时预加载核心模块
4.2 性能调优参数
| 参数 | 推荐值 | 作用域 | 说明 |
|---|---|---|---|
| keepalive_timeout | 65s | http | 保持连接超时时间 |
| client_body_timeout | 10s | http | 客户端请求体读取超时 |
| send_timeout | 10s | http | 响应发送超时 |
| lua_code_cache | on | http | 开启 Lua 代码缓存 |
| worker_connections | 32768 | events | 单个 worker 最大连接数 |
5. Lua 脚本开发实践
5.1 JWT 认证实现
/etc/openresty/lua/modules/auth.lua
lua复制local jwt = require "resty.jwt"
local util = require "resty.util"
local _M = {}
function _M.check()
local auth_header = ngx.var.http_Authorization
if not auth_header then
return util.return_error(401, "Missing Authorization header")
end
local token = string.match(auth_header, "Bearer%s+(.+)")
if not token then
return util.return_error(401, "Invalid token format")
end
local jwt_obj = jwt:verify("your-secret-key", token)
if not jwt_obj.verified then
return util.return_error(403, "Invalid token: "..(jwt_obj.reason or ""))
end
-- 将用户信息传递给后续阶段
ngx.ctx.user_id = jwt_obj.payload.sub
end
return _M
性能优化技巧:
- 使用 ngx.ctx 而非 ngx.var 传递上下文数据,减少性能开销
- 错误处理使用短路返回,避免不必要的逻辑执行
- 将密钥存储在共享字典中,支持热更新
5.2 分布式限流方案
结合 Redis 实现集群级别的限流控制:
lua复制local redis = require "resty.redis"
local util = require "resty.util"
local function rate_limit(key, limit, window)
local red = redis:new()
red:set_timeout(500) -- 500ms 超时
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "Redis connect failed: ", err)
return true -- 失败时放行
end
local current = red:get(key)
if current and tonumber(current) >= limit then
return false
end
local remaining = red:incr(key)
if remaining == 1 then
red:expire(key, window)
end
return true
end
算法选择建议:
- 令牌桶算法:适合突发流量场景
- 滑动窗口计数:精确控制单位时间请求量
- 漏桶算法:保证恒定输出速率
6. 监控与性能分析
6.1 指标采集方案
使用 Prometheus 进行指标暴露:
lua复制local prometheus = require "resty.prometheus".init("nginx_metrics")
local metric_requests = prometheus:counter(
"nginx_http_requests_total",
"Number of HTTP requests",
{"host", "status"}
)
log_by_lua_block {
metric_requests:inc(1, {ngx.var.host, ngx.var.status})
}
关键监控指标包括:
- 请求吞吐量(QPS)
- 响应时间分布(P50/P95/P99)
- 错误率(4xx/5xx)
- Lua 虚拟机内存使用
6.2 性能测试方法
使用 wrk 进行负载测试的推荐命令:
bash复制# 基准测试
wrk -t12 -c10000 -d60s --latency http://localhost/api/v1/test
# 带认证头的测试
wrk -t12 -c5000 -d30s -H "Authorization: Bearer xxx" http://localhost/api/v1/auth
测试报告应包含:
- 吞吐量(Requests/sec)
- 延迟分布(Latency Distribution)
- 错误统计(Non-2xx/3xx responses)
- 系统资源监控(CPU/Memory/Network)
7. 生产环境部署建议
7.1 高可用架构
推荐的多节点部署方案:
code复制 [负载均衡器]
/ | \
[网关节点1] [网关节点2] [网关节点3]
/ | \
[业务服务集群] [缓存集群] [数据库集群]
7.2 灰度发布策略
通过 Lua 实现流量切分:
lua复制local traffic_ratio = 0.1 -- 10% 流量到新版本
if math.random() < traffic_ratio then
ngx.var.backend = "new_version_backend"
else
ngx.var.backend = "stable_backend"
end
7.3 故障排查指南
常见问题及解决方法:
-
连接泄漏:
- 检查 keepalive 配置
- 使用
lua_socket_keepalive_timeout
-
Lua 内存增长:
- 避免在热路径上创建临时表
- 定期调用
collectgarbage
-
性能突降:
- 检查共享字典使用率
- 监控 LuaJIT 的 GC 暂停时间
8. 进阶优化技巧
8.1 热点数据缓存
使用 lua-resty-lrucache 实现本地缓存:
lua复制local lrucache = require "resty.lrucache"
local cache, err = lrucache.new(200) -- 200个缓存项
local function get_user(user_id)
local user = cache:get(user_id)
if user then
return user
end
-- 数据库查询逻辑
user = db_query(user_id)
cache:set(user_id, user)
return user
end
8.2 动态配置管理
通过共享字典实现配置热更新:
lua复制local function get_config(key)
local dict = ngx.shared.config_store
local value = dict:get(key)
if not value then
value = load_from_db(key)
dict:set(key, value)
end
return value
end
8.3 链路追踪集成
支持 OpenTelemetry 的示例:
lua复制local otel = require "opentelemetry.trace"
local tracer = otel.tracer("nginx-gateway")
local function handle_request()
local ctx = tracer:start_span("api-request")
-- 业务处理逻辑
tracer:end_span(ctx)
end
在实际部署中,我们发现当 worker_connections 设置为 32768 时,需要相应调整系统的最大文件描述符限制。通过以下命令可以验证当前设置:
bash复制cat /proc/$(cat /usr/local/openresty/nginx/logs/nginx.pid)/limits | grep 'Max open files'
对于需要处理大量静态资源的场景,建议在 Nginx 配置中添加以下优化指令:
nginx复制location ~* \.(jpg|png|css|js)$ {
open_file_cache max=1000 inactive=60s;
open_file_cache_valid 120s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
expires 1y;
add_header Cache-Control "public";
}
当遇到性能瓶颈时,可以通过 SystemTap 进行深度分析。以下脚本可以检测 Lua 函数的执行时间:
bash复制stap -e 'probe process("/usr/local/openresty/luajit/bin/luajit").function("*") {
println(tid(), " ", pp(), " ", gettimeofday_ns())
}'
对于需要更高性能的场景,可以考虑使用 FFI 直接调用 C 库函数。以下示例展示了如何调用 libc 的数学函数:
lua复制local ffi = require "ffi"
ffi.cdef[[
double sqrt(double x);
]]
local math_sqrt = ffi.C.sqrt
ngx.say("Square root of 16 is ", math_sqrt(16))
在长时间运行的网关服务中,内存管理尤为重要。建议定期检查 LuaJIT 的内存状态:
lua复制local function check_memory()
local stats = require "jit.util".memoryinfo()
ngx.log(ngx.NOTICE,
"LuaJIT memory: ",
stats.allocated/1024, "KB used / ",
stats.freed/1024, "KB freed")
end
对于需要处理 JSON 数据的场景,性能对比测试显示,使用 lua-cjson 比纯 Lua 实现的库快 10 倍以上。安装和使用方法:
bash复制luarocks install lua-cjson
lua复制local cjson = require "cjson.safe"
local data = cjson.decode('{"key":"value"}')
在安全方面,除了 JWT 验证外,还应实施以下防护措施:
lua复制-- 请求体大小限制
if tonumber(ngx.var.http_content_length) > 1024*1024 then
ngx.exit(413)
end
-- 请求频率限制
local limit = require "resty.limit.req"
local limiter = limit.new("my_limit_store", 100, 60) -- 100 req/min
local delay, err = limiter:incoming(ngx.var.remote_addr, true)
if not delay then
ngx.exit(429)
end
对于需要与数据库交互的场景,连接池的正确使用至关重要:
lua复制local mysql = require "resty.mysql"
local db, err = mysql:new()
local function query(sql)
if not db then
return nil, "failed to instantiate mysql"
end
db:set_timeout(1000) -- 1 second timeout
local ok, err, errcode, sqlstate = db:connect{
host = "127.0.0.1",
port = 3306,
database = "api_gateway",
user = "user",
password = "password",
max_packet_size = 1024*1024,
pool = "api_pool",
pool_size = 100
}
-- 查询逻辑
-- 将连接放回连接池
db:set_keepalive(10000, 100)
end
在微服务架构中,服务发现是核心需求。以下是基于 Consul 的实现示例:
lua复制local http = require "resty.http"
local json = require "cjson"
local function discover_service(service_name)
local httpc = http.new()
local res, err = httpc:request_uri("http://consul:8500/v1/catalog/service/"..service_name)
if not res then
return nil, "failed to query consul: "..err
end
local instances = json.decode(res.body)
if #instances == 0 then
return nil, "no available instances"
end
-- 简单的轮询负载均衡
local idx = (math.random(100) % #instances) + 1
return instances[idx].ServiceAddress, instances[idx].ServicePort
end
对于需要处理文件上传的场景,需要注意内存使用:
nginx复制location /upload {
client_max_body_size 10m;
client_body_buffer_size 128k;
content_by_lua_block {
local upload = require "resty.upload"
local chunk_size = 4096
local form = upload:new(chunk_size)
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
if typ == "eof" then
break
end
-- 处理上传数据
end
}
}
在日志处理方面,结构化日志能显著提升分析效率:
lua复制local function log_request()
local log_data = {
time = ngx.localtime(),
host = ngx.var.host,
uri = ngx.var.request_uri,
status = ngx.var.status,
latency = ngx.var.request_time,
upstream_latency = ngx.var.upstream_response_time,
client_ip = ngx.var.remote_addr,
user_agent = ngx.var.http_user_agent,
referer = ngx.var.http_referer
}
local logger = ngx.log
logger(ngx.INFO, cjson.encode(log_data))
end
对于国际化需求,可以使用 gettext 实现多语言支持:
lua复制local gettext = require "resty.gettext"
local locale = ngx.var.http_accept_language or "en_US"
local t = gettext.translator("/path/to/locale", locale)
ngx.say(t("Welcome_message"))
在性能调优过程中,火焰图是强大的分析工具。生成步骤:
bash复制# 安装 SystemTap 工具
sudo dnf install systemtap systemtap-runtime
# 生成 Nginx 火焰图
stap -v -e 'probe process("nginx").function("*") {
println(pp(), " ", gettimeofday_ns())
}' > nginx.trace
# 使用 FlameGraph 工具生成图片
stackcollapse-stap.pl nginx.trace | flamegraph.pl > nginx.svg
对于需要处理 XML 的场景,性能对比显示:
lua复制-- lua-expat 比纯 Lua 实现快 20 倍
local expat = require "lxp"
local parser = expat.new()
parser:parse(xml_string)
在缓存策略方面,多级缓存能显著提升性能:
lua复制local function get_data(key)
-- 1. 检查本地 LRU 缓存
local data = lru_cache:get(key)
if data then return data end
-- 2. 检查共享字典缓存
data = ngx.shared.cache:get(key)
if data then
lru_cache:set(key, data)
return data
end
-- 3. 检查 Redis
local redis_data = redis_get(key)
if redis_data then
ngx.shared.cache:set(key, redis_data, 60) -- 缓存60秒
return redis_data
end
-- 4. 回源查询
local db_data = db_query(key)
if db_data then
ngx.shared.cache:set(key, db_data, 300)
redis_set(key, db_data, 3600)
return db_data
end
end
对于需要处理 GraphQL 请求的场景:
lua复制local graphql = require "graphql"
local schema = graphql.new([[ type Query { hello: String! } ]])
local resolvers = {
hello = function() return "world" end
}
local result = schema:execute('{ hello }', resolvers)
ngx.say(result.data.hello) -- 输出 "world"
在 TCP 层负载均衡场景中,可以使用 stream 模块:
nginx复制stream {
upstream backend {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
}
}
对于需要处理 WebSocket 的场景:
nginx复制location /ws {
lua_socket_log_errors off;
content_by_lua_block {
local server = require "resty.websocket.server"
local wb, err = server:new()
while true do
local data, typ, err = wb:recv_frame()
if not data then
break
end
-- 处理消息
wb:send_text("echo: "..data)
end
}
}
在需要与 gRPC 服务交互时:
lua复制local grpc = require "grpc"
local client = grpc.new("127.0.0.1:50051")
local res, err = client:call("helloworld.Greeter", "SayHello", {name="world"})
对于需要处理 Protocol Buffers 的场景:
lua复制local pb = require "pb"
pb.loadfile("person.pb")
local person = {
name = "John",
id = 1234,
email = "john@example.com"
}
local data = pb.encode("Person", person)
local decoded = pb.decode("Person", data)
在需要实现 AB 测试的场景中:
lua复制local function get_variant(user_id)
local hash = ngx.crc32_long(user_id) % 100
if hash < 10 then -- 10% 流量到Variant A
return "A"
else
return "B"
end
end
对于需要处理地理位置信息的场景:
lua复制local geo = require "resty.geoip"
local geoip = geo.new("/path/to/GeoIP.dat")
local country = geoip:query_country("8.8.8.8")
在需要生成唯一 ID 的场景下:
lua复制local snowflake = require "snowflake"
local generator = snowflake.new(1) -- worker ID
local id = generator:next_id()
对于需要处理图片的场景,可以使用 ImageMagick 绑定:
lua复制local magick = require "magick"
local image = magick.open("input.jpg")
image:resize(800, 600)
image:write("output.jpg")
在需要处理 Markdown 文档的场景:
lua复制local cmark = require "cmark"
local html = cmark.markdown_to_html("# Hello\nWorld")
对于需要与 Kafka 交互的场景:
lua复制local kafka = require "resty.kafka"
local producer = kafka.new_producer({"127.0.0.1:9092"})
local offset, err = producer:send("test_topic", nil, "message")
在需要处理日期时间的复杂场景:
lua复制local date = require "date"
local now = date()
local tomorrow = now:adddays(1)
对于需要实现定时任务的场景:
lua复制local timer = require "resty.timer"
timer.every(60, function()
-- 每分钟执行的任务
end)
在需要处理正则表达式的高性能场景:
lua复制local re = require "rex_pcre2"
local match = re.match("hello world", "\\w+")
对于需要处理 YAML 配置的场景:
lua复制local yaml = require "lyaml"
local config = yaml.load([[
key: value
list:
- item1
- item2
]])
在需要实现服务熔断的场景:
lua复制local circuit_breaker = require "resty.circuit"
local cb = circuit_breaker.new{
timeout = 10, -- 熔断持续时间
threshold = 5, -- 连续失败次数
window = 60 -- 统计窗口(秒)
}
local ok, err = cb:call(function()
return risky_operation()
end)
对于需要处理货币计算的场景:
lua复制local decimal = require "decimal"
local total = decimal.new("10.99"):add("5.50")
在需要实现分布式锁的场景:
lua复制local lock = require "resty.lock"
local locker = lock:new("my_locks")
local elapsed, err = locker:lock("resource_key")
if not elapsed then
ngx.say("failed to acquire lock: ", err)
end
-- 业务逻辑
local ok, err = locker:unlock()
对于需要处理 HTML 模板的场景:
lua复制local template = require "resty.template"
template.render("view.html", {
title = "Hello",
items = {"a", "b", "c"}
})
在需要处理二进制协议的场景:
lua复制local struct = require "struct"
local packed = struct.pack(">I4I4", 123, 456)
local a, b = struct.unpack(">I4I4", packed)
对于需要实现权重随机选择的场景:
lua复制local weight_random = require "resty.weight_random"
local wr = weight_random.new({
{"A", 70}, -- 70% 概率
{"B", 30} -- 30% 概率
})
local selected = wr:next()
在需要处理 CSV 数据的场景:
lua复制local csv = require "csv"
local data = csv.open("data.csv")
for fields in data:lines() do
-- 处理每行数据
end
对于需要实现布隆过滤器的场景:
lua复制local bloom = require "resty.bloom"
local bf = bloom.new(10000, 0.01) -- 容量1万,错误率1%
bf:add("item1")
local exists = bf:contains("item1")
在需要处理数学计算的场景:
lua复制local ffi = require "ffi"
ffi.cdef[[
double sin(double x);
double cos(double x);
]]
local math_sin = ffi.C.sin
local math_cos = ffi.C.cos
对于需要生成测试数据的场景:
lua复制local fake = require "resty.fake"
local name = fake.name()
local email = fake.email()
在需要处理 IP 地址的场景:
lua复制local ipmatcher = require "resty.ipmatcher"
local matcher = ipmatcher.new({"192.168.0.0/24"})
local allowed = matcher:match("192.168.0.1")
对于需要处理大整数计算的场景:
lua复制local bigint = require "resty.bigint"
local a = bigint.new("12345678901234567890")
local b = a:add("98765432109876543210")
在需要实现速率限制的高级场景:
lua复制local limit = require "resty.limit.count"
local limiter = limit.new("my_limit_store", 100, 60) -- 100 req/min
local delay, err = limiter:incoming(ngx.var.remote_addr, true)
if not delay then
ngx.exit(429)
end
对于需要处理压缩数据的场景:
lua复制local zlib = require "zlib"
local compressed = zlib.deflate()("data to compress")
local original = zlib.inflate()(compressed)
在需要生成密码哈希的场景:
lua复制local bcrypt = require "bcrypt"
local hash = bcrypt.digest("password", 10)
local valid = bcrypt.verify("password", hash)
对于需要处理时区转换的场景:
lua复制local tz = require "resty.timezone"
local utc_time = os.time()
local local_time = tz.utc_to_local(utc_time, "Asia/Shanghai")
在需要生成 UUID 的场景:
lua复制local uuid = require "resty.uuid"
local id = uuid.generate()
对于需要处理信号量的场景:
lua复制local semaphore = require "ngx.semaphore"
local sem = semaphore.new()
sem:post()
sem:wait(1) -- 1秒超时
在需要实现优先级队列的场景:
lua复制local pq = require "resty.priority_queue"
local queue = pq.new()
queue:push("item1", 10)
queue:push("item2", 5)
local item = queue:pop() -- 返回优先级最高的item2
对于需要处理系统信号的场景:
lua复制local signal = require "resty.signal"
signal.register("TERM", function()
-- 清理逻辑
os.exit(0)
end)
在需要实现对象池的场景:
lua复制local pool = require "resty.objectpool"
local create_obj = function() return {} end
local obj_pool = pool.new(create_obj, 10) -- 最大10个对象
local obj = obj_pool:get()
obj_pool:put(obj)
对于需要处理网络子网的场景:
lua复制local subnet = require "resty.subnet"
local net = subnet.new("192.168.1.0/24")
local contains = net:contains("192.168.1.10")
在需要实现事件总线的场景:
lua复制local event = require "resty.event"
event.on("user.created", function(data)
-- 处理事件
end)
event.emit("user.created", {id=123})
对于需要处理颜色值的场景:
lua复制local color = require "resty.color"
local red = color.new("#ff0000")
local light_red = red:lighten(0.2)
在需要实现状态机的场景:
lua复制local fsm = require "resty.fsm"
local machine = fsm.new({
initial = "green",
events = {
{name = "warn", from = "green", to = "yellow"},
{name = "panic", from = "yellow", to = "red"}
}
})
machine:warn()
对于需要处理几何计算的场景:
lua复制local geo = require "resty.geometry"
local circle = geo.circle(0, 0, 5)
local contains = circle:contains(3, 4)
在需要实现观察者模式的场景:
lua复制local observable = require "resty.observable"
local obj = observable.new()
obj:on("change", function(data) end)
obj:emit("change", {value=1})
对于需要处理音视频元数据的场景:
lua复制local media = require "resty.media"
local info = media.analyze("video.mp4")
在需要实现数据验证的场景:
lua复制local validator = require "resty.validation"
local rules = {
username = validator.string.min(3).max(20),
age = validator.number.min(18)
}
local valid, err = validator.check(rules, input)
对于需要处理文件类型的场景:
lua复制local filetype = require "resty.filetype"
local kind = filetype.detect("data.bin")
在需要实现重试逻辑的场景:
lua复制local retry = require "resty.retry"
local ok, err = retry(3, function()
return unreliable_operation()
end)
对于需要处理货币格式的场景:
lua复制local money = require "resty.money"
local amount = money.new("1234.56"):format("USD")
在需要实现缓存击穿保护的场景:
lua复制local lock = require "resty.lock"
local function get_data(key)
local data = cache:get(key)
if data ~= nil then return data end
local locker = lock:new("cache_locks")
local elapsed, err = locker:lock(key)
if not elapsed then
return nil, "failed to acquire lock"
end
-- 检查缓存是否已被其他进程填充
data = cache:get(key)
if data ~= nil then
locker:unlock()
return data
end
-- 回源查询
data = db_query(key)
cache:set(key, data)
locker:unlock()
return data
end
对于需要处理大文件上传的场景:
nginx复制location /upload {
client_max_body_size 100m;
client_body_temp_path /tmp/nginx_upload;
content_by_lua_block {
local upload = require "resty.upload"
local form = upload:new(4096) -- 4KB chunks
while true do
local typ, res, err = form:read()
if not typ then
ngx.log(ngx.ERR, "upload failed: ", err)
return ngx.exit(500)
end
if typ == "eof" then break end
-- 处理上传块
end
}
}
在需要实现长轮询的场景:
lua复制local long_poll = require "resty.long_poll"
local poller = long_poll.new()
poller:subscribe("channel1", function(message)
ngx.say(message)
end)
-- 在另一个请求中
poller:publish("channel1", "new data")
对于需要处理地理位置围栏的场景:
lua复制local geofence = require "resty.geofence"
local fence = geofence.new()
fence:add_polygon({{lat=1,lng=1}, {lat=1,lng=2}, {lat=2,lng=2}})
local inside = fence:contains({lat=1.5, lng=1.5})
在需要实现任务队列的场景:
lua复制local queue = require "resty.queue"
local task_queue = queue.new("my_tasks")
task_queue:push("task_data")
local task = task_queue:pop()
对于需要处理时间序列数据的场景:
lua复制local ts = require "resty.timeseries"
local series = ts.new()
series:add(os.time(), 42)
local avg = series:avg(60) -- 60秒窗口平均值
在需要实现分布式 ID 生成的场景:
lua复制local snowflake = require "snowflake"
local generator = snowflake.new(1