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;
}

十、结语

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

相关推荐
那个失眠的夜2 天前
Spring 的纯注解配置
xml·java·数据库·后端·spring·junit
liulilittle2 天前
Lua 浮点数比较
开发语言·junit·lua
rannn_1113 天前
【Redis|高级篇2】多级缓存|JVM进程缓存、Lua语法、多级缓存实现(OpenResty)、缓存同步(Canal)
java·redis·分布式·后端·缓存·lua·openresty
jaysee-sjc6 天前
十七、Java 高级技术入门全解:JUnit、反射、注解、动态代理
java·开发语言·算法·junit·intellij-idea
橘子编程7 天前
软件测试全流程实战指南
java·功能测试·测试工具·junit·tomcat·压力测试·可用性测试
夜影风7 天前
Tengine、OpenResty与Nginx三大Web服务中间件对比分析
nginx·openresty·技术架构
DJ斯特拉11 天前
Redis使用lua脚本
junit·单元测试·lua
2301_7717172111 天前
idea中springboot中使用junit测试报错的解决方案
spring boot·junit·intellij-idea
難釋懷12 天前
OpenResty实现Redis查询
数据库·redis·openresty
Java成神之路-12 天前
Spring 整合 MyBatis 全流程详解(附 Junit 单元测试实战)(Spring系列6)
spring·junit·mybatis