OpenResty快速入门

一、前言:为什么你需要 OpenResty?

你是否遇到过这些痛点?

  • ❌ 业务逻辑必须放在后端,Nginx 只能做简单转发
  • ❌ 鉴权、限流、日志等通用功能重复开发
  • ❌ 高并发下后端压力大,响应慢

OpenResty = Nginx + LuaJIT ,让你在 Nginx 层直接编写业务逻辑 ,实现:

毫秒级响应

百万 QPS 承载能力

统一网关控制(鉴权、限流、日志、灰度)

本文将带你10 分钟快速上手 OpenResty,从配置到写第一个 Lua 脚本!


二、OpenResty 核心优势

能力 说明
🚀 高性能 基于 Nginx 事件驱动 + LuaJIT JIT 编译
💡 可编程 在 Nginx 配置中嵌入 Lua 代码
🔌 丰富生态 内置 Redis、MySQL、HTTP 客户端
🛡️ 企业级应用 被阿里、腾讯、360、Kong 等广泛使用

💡 一句话理解:OpenResty 让 Nginx 从"静态代理"变成"动态网关"。


三、OpenResty 请求处理阶段(关键!)

OpenResty 在 Nginx 的基础上扩展了多个 Lua 执行阶段,最常用的是:

XML 复制代码
server {
    location /test {
        # 1. 初始化(全局)
        init_by_lua_block { ... }

        # 2. 重写阶段(改写 URI/参数)
        rewrite_by_lua_block { ... }

        # 3. 访问阶段(核心逻辑)
        access_by_lua_block { ... }

        # 4. 内容生成阶段(返回响应)
        content_by_lua_block { ... }

        # 5. 日志阶段
        log_by_lua_block { ... }
    }
}

新手重点掌握access_by_lua_block(鉴权/限流)和 content_by_lua_block(返回数据)


四、实战 1:Hello World!

4.1 修改配置文件

编辑 /usr/local/openresty/nginx/conf/nginx.conf(或 /etc/openresty/nginx.conf):

XML 复制代码
server {
    listen 80;
    server_name localhost;

    location /hello {
        default_type 'text/plain';
        content_by_lua_block {
            ngx.say("Hello, OpenResty!")
            ngx.say("Current time: ", ngx.now())
        }
    }
}

4.2 重载配置 & 测试

bash 复制代码
# 重载配置(不中断服务)
sudo openresty -s reload

# 测试
curl http://localhost/hello

输出

复制代码
Hello, OpenResty!
Current time: 1730123456.789

🎉 恭喜!你已成功运行第一个 OpenResty 脚本!


五、实战 2:实现 IP 黑名单(access 阶段)

bash 复制代码
location /api/ {
    access_by_lua_block {
        local black_ips = {
            ["192.168.1.100"] = true,
            ["10.0.0.5"] = true
        }
        local client_ip = ngx.var.remote_addr
        if black_ips[client_ip] then
            ngx.log(ngx.WARN, "Blocked IP: ", client_ip)
            ngx.exit(403)  -- 直接返回 403
        end
        -- 继续后续处理(如反向代理)
    }

    # 反向代理到后端
    proxy_pass http://backend;
}

优势 :在 Nginx 层拦截恶意请求,不消耗后端资源


六、实战 3:调用 Redis 实现限流

6.1 安装 lua-resty-redis(通常已内置)

OpenResty 默认包含 resty.redis 模块。

6.2 限流脚本(每秒最多 5 次)

bash 复制代码
location /limited {
    access_by_lua_block {
        local redis = require "resty.redis"
        local red = redis:new()
        red:set_timeout(1000)  -- 1s 超时

        local ok, err = red:connect("127.0.0.1", 6379)
        if not ok then
            ngx.log(ngx.ERR, "Redis connect failed: ", err)
            ngx.exit(500)
        end

        local key = "rate_limit:" .. ngx.var.remote_addr
        local requests = red:get(key)

        if not requests or requests == ngx.null then
            red:set(key, 1)
            red:expire(key, 1)  -- 1秒过期
        elseif tonumber(requests) >= 5 then
            ngx.log(ngx.WARN, "Rate limit exceeded for ", ngx.var.remote_addr)
            ngx.exit(429)
        else
            red:incr(key)
        end

        red:close()
    }

    content_by_lua_block {
        ngx.say("Request allowed!")
    }
}

🔥 效果:单 IP 每秒最多 5 次请求,超限返回 429。


七、常用 Lua 模块与 API

模块/变量 用途
ngx.var.remote_addr 客户端 IP
ngx.req.get_headers() 获取请求头
ngx.req.read_body() + ngx.req.get_post_args() 获取 POST 参数
ngx.redirect(url) 重定向
ngx.print() / ngx.say() 输出响应
ngx.exit(code) 终止请求并返回状态码
require "resty.redis" Redis 客户端
require "resty.http" HTTP 客户端

八、调试技巧

8.1 查看日志

bash 复制代码
# 错误日志
tail -f /usr/local/openresty/nginx/logs/error.log

# 访问日志(需配置 log_by_lua_block)

8.2 打印调试信息

Lua 复制代码
ngx.log(ngx.INFO, "Debug: user_id=", user_id)

⚠️ 注意:生产环境避免打印敏感信息!


九、最佳实践建议

轻量逻辑 :Lua 脚本执行时间 < 10ms,避免阻塞 Nginx

连接池 :使用 resty.redis 的连接池(set_keepalive

错误处理 :始终检查 ok, err = ...

配置分离 :复杂逻辑抽离为 .lua 文件,用 content_by_lua_file 引入

Lua 复制代码
location /complex {
    content_by_lua_file /etc/openresty/lua/my_logic.lua;
}

十、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
童话的守望者1 天前
BookHub (RWCTF 2018) 通关
junit
吴懿不在2 天前
apisix~OpenResty各阶段的介绍
openresty
techdashen4 天前
Uber 如何完成超大规模 JUnit 迁移:从 JUnit 4 到 JUnit 5 的自动化工程实践
junit·sqlserver·自动化
章老师说5 天前
NGINX官方谈Lua风险:这其实是两条网关技术路线之争
运维·nginx·负载均衡·lua·openresty
会周易的程序员6 天前
使用 LuaBridge 封装 C++ 日志库 microLog 为 Lua 模块
c++·物联网·junit·lua·日志·iot·aiot
欢呼的太阳7 天前
在上一篇随笔中介绍了四种编程语言。这次再介绍四种编程语言:Fortran、Lua、Lisp 和 Logo。
junit·lua·lisp
Full Stack Developme7 天前
SpringBoot JUnit 教程
数据库·spring boot·spring·junit
殳翰8 天前
spring对junit的支持
spring·junit·sqlserver
许彰午1 个月前
39_Java单元测试JUnit入门
java·junit·单元测试
骇客之技术1 个月前
AutoLua:在安卓上写 Lua 脚本
android·junit·lua