Lua 小白入门教程Lua 小白入门教程
首页
基础教程
实战进阶
编程指南
首页
基础教程
实战进阶
编程指南
  • 实战进阶

    • 🚀 实战进阶
    • 第1章 - 模块与包管理
    • 第2章 - 文件 I/O 操作
    • 第3章 - 错误处理
    • 第4章 - 面向对象编程
    • 第5章 - SpringBoot + Lua 整合实战 ⭐
    • 第6章 - Redis + Lua 脚本 ⭐
    • 第7章 - OpenResty 入门
    • 第8章 - 最佳实践与常见坑

第7章 - OpenResty 入门

嗨,朋友!我是长安。

这一章我们来了解 OpenResty——一个基于 Nginx + Lua 的高性能 Web 平台。很多互联网公司用它来做 API 网关、WAF(Web 应用防火墙)、动态路由等。

🤔 OpenResty 是什么?

简单来说:OpenResty = Nginx + LuaJIT + 一堆好用的 Lua 库

特性说明
基于 Nginx继承了 Nginx 的高性能和高并发能力
内嵌 LuaJIT在 Nginx 中直接运行 Lua 代码
非阻塞 I/OLua 代码也是非阻塞的,不会降低 Nginx 性能
丰富的库HTTP 客户端、Redis 客户端、MySQL 客户端等

为什么 Java 程序员要了解它?

  • API 网关 — 很多公司用 OpenResty 做网关,Java 服务在后面
  • 限流/鉴权 — 在 Nginx 层做限流和鉴权,减轻后端压力
  • 灰度发布 — 用 Lua 脚本控制流量分发
  • 动态路由 — 根据请求参数动态选择后端服务
                    OpenResty (Nginx + Lua)
                    ┌────────────────────┐
用户请求 ──────────►│  限流 │ 鉴权 │ 路由 │
                    └────────┬───────────┘
                             │
                    ┌────────┼───────────┐
                    ▼        ▼           ▼
              SpringBoot  SpringBoot  SpringBoot
              服务 A       服务 B       服务 C

🚀 安装 OpenResty

macOS

brew install openresty/brew/openresty

Linux (Ubuntu)

# 添加 APT 仓库
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
sudo apt-get update
sudo apt-get install -y openresty

Windows

从 OpenResty 官网 下载 Windows 版本。

验证安装

openresty -v
# nginx version: openresty/1.25.x.x

📖 Hello World

项目结构

my-openresty/
├── conf/
│   └── nginx.conf
├── logs/
└── lua/
    └── hello.lua

nginx.conf

worker_processes 1;
error_log logs/error.log;

events {
    worker_connections 1024;
}

http {
    server {
        listen 8080;
        
        # 直接在配置中写 Lua
        location /hello {
            content_by_lua_block {
                ngx.say("Hello, OpenResty!")
            }
        }
        
        # 引用外部 Lua 文件
        location /api {
            content_by_lua_file lua/hello.lua;
        }
    }
}

lua/hello.lua

-- 获取请求参数
local args = ngx.req.get_uri_args()
local name = args.name or "World"

-- 设置响应头
ngx.header["Content-Type"] = "application/json"

-- 返回 JSON 响应
local cjson = require("cjson")
local response = {
    message = "Hello, " .. name .. "!",
    method = ngx.req.get_method(),
    uri = ngx.var.uri,
    time = ngx.now()
}

ngx.say(cjson.encode(response))

启动和测试

# 启动
openresty -p /path/to/my-openresty/

# 测试
curl http://localhost:8080/hello
# Hello, OpenResty!

curl "http://localhost:8080/api?name=长安"
# {"message":"Hello, 长安!","method":"GET","uri":"/api","time":1706000000}

🔧 Nginx Lua 执行阶段

OpenResty 的 Lua 代码在 Nginx 的不同处理阶段执行:

指令阶段用途
init_by_lua启动时加载全局配置
init_worker_by_luaWorker 启动时初始化定时器
set_by_luarewrite 阶段设置变量
rewrite_by_luarewrite 阶段URL 重写
access_by_luaaccess 阶段鉴权、限流
content_by_luacontent 阶段生成响应
header_filter_by_lua响应头阶段修改响应头
body_filter_by_lua响应体阶段修改响应体
log_by_lualog 阶段自定义日志

🌟 实战:API 限流

-- lua/rate_limit.lua
-- 基于令牌桶的接口限流

local limit_count = ngx.shared.limit_count    -- 需要在 nginx.conf 中声明共享内存

local function rate_limit(key, limit, window)
    local count, err = limit_count:get(key)
    
    if not count then
        -- 第一次请求
        limit_count:set(key, 1, window)
        return true
    end
    
    if count >= limit then
        return false    -- 超过限制
    end
    
    limit_count:incr(key, 1)
    return true
end

-- 获取客户端 IP
local client_ip = ngx.var.remote_addr
local key = "rate:" .. client_ip

-- 每秒最多 10 次请求
if not rate_limit(key, 10, 1) then
    ngx.status = 429
    ngx.say('{"error": "Too Many Requests"}')
    return ngx.exit(429)
end

-- 通过限流,继续处理...
# nginx.conf 中声明共享内存
http {
    lua_shared_dict limit_count 10m;
    
    server {
        listen 8080;
        
        location /api/ {
            access_by_lua_file lua/rate_limit.lua;
            proxy_pass http://backend;
        }
    }
}

🌟 实战:JWT 鉴权

-- lua/auth.lua
-- JWT Token 验证

local cjson = require("cjson")

-- 获取 Authorization 头
local auth_header = ngx.req.get_headers()["Authorization"]
if not auth_header then
    ngx.status = 401
    ngx.say('{"error": "Missing Authorization header"}')
    return ngx.exit(401)
end

-- 提取 Token
local token = auth_header:match("Bearer%s+(.+)")
if not token then
    ngx.status = 401
    ngx.say('{"error": "Invalid token format"}')
    return ngx.exit(401)
end

-- 简单的 Token 验证(实际项目中应该验证 JWT 签名)
-- 这里只是演示,生产环境请使用 lua-resty-jwt 库
local decoded = ngx.decode_base64(token)
if not decoded then
    ngx.status = 401
    ngx.say('{"error": "Invalid token"}')
    return ngx.exit(401)
end

-- 验证通过,将用户信息传给后端
ngx.req.set_header("X-User-Id", "extracted-user-id")

🌟 实战:动态路由(灰度发布)

-- lua/gray_route.lua
-- 灰度发布路由

local gray_users = ngx.shared.gray_users    -- 灰度用户列表

local function is_gray_user(user_id)
    if gray_users:get(user_id) then
        return true
    end
    
    -- 也可以按百分比灰度
    local hash = ngx.crc32_long(user_id)
    local percent = hash % 100
    return percent < 10    -- 10% 的用户走灰度
end

-- 获取用户 ID(从 header 或 cookie)
local user_id = ngx.req.get_headers()["X-User-Id"] or "anonymous"

if is_gray_user(user_id) then
    -- 灰度用户 → 新版本服务
    ngx.var.backend = "http://service-v2:8080"
else
    -- 正常用户 → 稳定版本服务
    ngx.var.backend = "http://service-v1:8080"
end

📊 OpenResty vs SpringCloud Gateway

特性OpenRestySpringCloud Gateway
语言LuaJava
性能极高(C + LuaJIT)高(Reactor)
内存占用极低较高
学习成本需要学 Lua + NginxJava 生态内
生态Lua 库Spring 生态
适用场景超高并发、边缘计算微服务网关
动态配置修改 Lua 文件 + reload配置中心

如何选择?

  • 超高并发(10万+ QPS)→ OpenResty
  • Spring 生态内,团队都是 Java 技术栈 → SpringCloud Gateway
  • 两者结合:OpenResty 做边缘网关,SpringCloud Gateway 做内部网关

📝 小结

  • OpenResty = Nginx + LuaJIT,高性能 Web 平台
  • 常用场景:API 网关、限流、鉴权、灰度发布
  • Lua 代码在 Nginx 不同阶段执行(access、content 等)
  • 性能极高,适合超高并发场景
  • 可以和 SpringBoot 后端服务配合使用

➡️ 下一步

最后一章!来看看 最佳实践与常见坑,这是从实战中总结出来的经验。

💪 练习题

  1. 安装 OpenResty,创建一个返回 JSON 的简单 API。
  2. 实现一个基于 IP 的简单限流中间件。
  3. OpenResty 和 SpringCloud Gateway 各有什么优缺点?
  4. 在 OpenResty 中,access_by_lua 和 content_by_lua 分别在什么阶段执行?

答案提示

  1. 参考本章的 Hello World 示例
  2. 使用 ngx.shared 共享内存 + IP 作为 key 计数
  3. OpenResty 性能更高但需学 Lua,Gateway 在 Spring 生态内开发方便
  4. access_by_lua 在访问控制阶段(鉴权/限流),content_by_lua 在内容生成阶段(响应)
最近更新: 2026/2/27 17:54
Contributors: 王长安
Prev
第6章 - Redis + Lua 脚本 ⭐
Next
第8章 - 最佳实践与常见坑