核心思路是Nginx+Lua直连Redis查短码并302跳转,完全绕过应用服务器;需用OpenResty、配置lua_shared_dict本地缓存、设置合理TTL,并在location中用content_by_lua_block实现原子查询与重定向。

核心思路是:Nginx 接收短链请求(如 /aBc12),用 Lua 脚本查 Redis(或 MySQL)获取原始长链接,再执行 302 重定向跳转。整个过程不经过后端应用服务器,由 Nginx + Lua 直接完成,性能高、延迟低。
一、环境准备与模块依赖
必须使用支持 Lua 的 Nginx 发行版,推荐 OpenResty(已内置 ngx_http_lua_module 和 redis 支持):
- OpenResty ≥ 1.19.3.1(确保 LuaJIT 稳定、支持 cosocket)
- Redis 服务可访问(建议部署在同一内网,毫秒级响应)
- Nginx 配置中已启用
lua_package_path和lua_shared_dict(用于缓存热点短码)
二、短链存储与生成逻辑(前置)
短链本身不需 Nginx 生成,由业务系统(如 Python/Java 服务)生成并写入 Redis:
- Key:短码(如
aBc12),类型为 string - Value:原始 URL(如
https://mp.weixin.qq.com/mp/homepage?__biz=xxx&scene=xxx) - 建议设置 TTL(如 30 天),避免无限膨胀
- 可选:用 Lua 脚本在 Redis 层做原子计数(统计点击量)
三、Nginx + Lua 实现重定向
在 location 块中嵌入 Lua 逻辑,典型配置如下:
location ~ ^/([a-zA-Z0-9]{4,12})$ {
# 提取短码(捕获组 $1)
set $short_code $1;
<pre class="brush:php;toolbar:false;"># Lua 脚本执行查询与跳转
content_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(500)
-- 连 Redis(根据实际地址调整)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.status = 404
ngx.say("Short link not found")
return
end
-- 查询短码对应长链接
local res, err = red:get(ngx.var.short_code)
if not res then
ngx.status = 404
ngx.say("Invalid short code")
return
end
-- 成功:302 跳转(默认 status 是 302)
return ngx.redirect(res, 302)
}}
⚠️ 注意:return ngx.redirect(...) 必须显式加 return,否则后续代码仍会执行。
四、增强健壮性的小技巧
-
加本地缓存:用
lua_shared_dict缓存热门短码(减少 Redis 压力),查缓存失败再查 Redis -
防恶意高频请求:配合
limit_req限制单 IP 短链访问频率 -
记录日志:在 Lua 中调用
ngx.log(ngx.INFO, ...)记录短码、来源 IP、时间,便于审计和分析 - 兼容微信跳转限制:若目标是微信小程序,确保长链接已通过微信 URL Scheme 校验,且域名已在公众号/小程序后台配置业务域名











