千家信息网

如何通过 Lua 扩展 Nginx

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要讲解了"如何通过 Lua 扩展 Nginx",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何通过 Lua 扩展 Nginx"吧!1. ng
千家信息网最后更新 2026年11月03日如何通过 Lua 扩展 Nginx

这篇文章主要讲解了"如何通过 Lua 扩展 Nginx",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何通过 Lua 扩展 Nginx"吧!

1. ngx_lua 模块


  • Nginx 模块需要用 C 开发,而且必须符合一系列复杂的规则,最重要的用 C 开发模块必须要熟悉 Nginx 的源代码,使得开发者对其望而生畏。

  • ngx_lua 模块通过将 lua 解释器集成进 Nginx,可以采用 lua 脚本实现业务逻辑。

  • 该模块具有以下特性:

    • 高并发、非阻塞地处理各种请求。

    • Lua 内建协程,这样就可以很好地将异步回调转换成顺序调用的形式。

    • 每个协程都有一个独立的全局环境(变量空间),继承于全局共享的、只读的"comman data"。

  • 得益于 Lua 协程的支持,ngx_lua 在处理 10000 个并发请求时只需要很少的内存。根据测试,ngx_lua 处理每个请求只需要 2KB 的内存,如果使用 LuaJIT 则会更少。

  • ngx_lua 非常适合用于实现可扩展的、高并发的服务。

2. 协程(Coroutine)


1. 协程类似一种多线程,与多线程的区别
  • 协程并非 os 线程,所以创建、切换开销比线程相对较小。

  • 协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、开销很小。

  • 多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程间协作的关系,只有当一个协程主动放弃执行权,另一个协程才能取得执行权,所以在某一瞬间,多个协程间只有一个在运行。

  • 由于多个协程是只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。

  • 多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的。

Nginx 的每个 Worker 进程都是在 epoll 或 kqueue 这样的事件模型之上,封装成协程,每个请求都有一个协程进行处理。这正好与 Lua 内建协程的模型是一致的,所以即使 ngx_lua 需要执行 lua,相对 C 有一定的开销,但依然能保证高并发能力。

3. Nginx 进程模型


  • Nginx 采用多进程模型,单Master-多Worker,Master 进程主要用来管理 Worker 进程。

  • Worker 进程采用单线程、非阻塞地事件模型(Event Loop,事件循环)来实现端口的监听及客户端请求的处理和响应,同时 Worker 还要处理来自 Master 的信号。Worker 进程个数一般设置为机器 CPU 核数。

1. Master 进程具体包括如下 4 个主要功能
  • 接受来自外界的信号。

  • 向各 Worker 进程发送信号。

  • 监控 Worker 进程的运行状态。

  • 当 Worker 进程退出后(异常情况下),会自动重新启动新的 Worker 进程。

2. 进程模型

4. HTTP 请求处理


阶段说明
post-read读取请求内容阶段,nginx 读取并解析完请求头之后就立即开始运行
server-rewriteserver 请求地址重写阶段
find-config配置查找阶段,用来完成当前请求与 location 配置块之间的配置工作
rewritelocation 请求地址重写阶段,当 ngx_rewrite 指令用于 location 中,就是在这个阶段运行的
post-rewrite请求地址重写阶段,当 nginx 完成 rewrite 阶段所要求的内部跳转动作,如果 rewrite 阶段有这个要求的话
preaccess访问权限检查准备阶段,ngx_limit_req 和 ngx_limit_zone 在这个阶段运行,ngx_limit_req 可以控制请求的访问频率,ngx_limit_zone 可以控制访问的并发度。
access权限检查阶段,ngx_access 在这个阶段运行,配置指令多是执行访问控制相关的任务,入检查用户的访问权限,检查用户的来源 IP 是否合法
post-access访问权限检查提交阶段
try-files配置 try_files 处理阶段
content内容产生阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成 HTTP 响应内容的
log日志模块处理阶段

5. ngx_lua 指令


  • ngx_lua 属于 nginx 的一部分,它的执行指令都包含在 nginx 的 11 个步骤之中了,相应的处理阶段可以做插入式处理,即可插拔式架构,不过 ngx_lua 并不是所有阶段都会运行的;另外指令可以在 http、server、server if、location、location if 几个范围进行配置。

指令所处处理阶段使用范围解释
init_by_lua
init_by_lua_file
loading-confighttpnginx Master 进程加载配置时执行;
通常用于初始化全局配置/预加载 Lua 模块
init_worker_by_lua
init_worker_by_lua_file
starting-workerhttp每个 Nginx Worker 进程启动时调用的计时器,如果 Master 进程不允许
则只会在 init_by_\lua 之后调用;通常用于定时拉取配置/数据,
或者后端服务的健康检查。
set_by_lua
set_by_lua_file
rewriteserver,server if,location,location if设置 nginx 变量,可以实现复杂的赋值逻辑;此处是阻塞的,Lua 代码要做到非常快
write_by_lua
rewrite_by_lua_file
rewrite tailhttp,server,location,location ifrewrite 阶段处理,可以实现复杂的转发/重定向逻辑。
access_by_lua
access_by_lua_file
access tailhttp,server,location,location if请求访问阶段处理,用于访问控制
content_by_lua
content_by_lua_file
contentlocation,location if内容处理器,接受请求处理并输出响应
header_filter_by_lua
header_filter_by_lua_file
output-header-firsthttp,server,location,location if设置 header 和 cookie
body_filter_by_lua
body_filter_by_lua_file
output-body-filterhttp,server,location,location if对响应数据进行过滤,比如截断、替换
log_by_lua
log_by_lua_file
loghttp,server,location,location iflog 阶段处理,比如记录访问量/统计平均响应时间

6. OpenResty


1. 概念
  • OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

2. 工作原理
  • OpenResty 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调用 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10k 乃至 1000k 以上单机并发连接的高性能 Web 应用系统。

3. 目标
  • OpenResty 的目标是让你的 Web 服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。

7. ngx_lua 实例


  • content_by_lua:内容处理器,接收请求处理并输出响应。

  • 该指令工作在 Nginx 处理流程的 content 阶段,即内容产生阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成 HTTP 响应内容的。

  • 测试

    输出:$ curl http://127.0.0.1/$ Hello,world


1. 简单示例
user www-data;worker_processes auto;pid /run/nginx.pid;error_log logs/error.log;events {    worker_connections 1024;}http {    server {        listen 8080;        location / {            default_type text/html;            content_by_lua '                ngx.say("

Hello, world!

") '; } }}
user www-data;worker_processes auto;pid /run/nginx.pid;error_log logs/error.log;events {    worker_connections 1024;}http {    server {        listen 8080;        location / {            default_type text/html;            content_by_lua_block {                ngx.say('Hello, world!')            }        }    }}
启动/usr/local/openresty/nginx/sbin/nginx -p `pwd` -c conf/nginx_openresty_01.conf测试curl -i http://127.0.0.1/
2. 休眠示例
user www-data;worker_processes auto;pid /run/nginx.pid;error_log logs/error.log;events {    worker_connections 1024;}http {    server {        listen 8080;        location /lua_1 {            default_type text/html;            content_by_lua_block {                ngx.say('Hello, world! @ Time 1!')                ngx.sleep(3)                ngx.say('Hello, world! @ Time 2!')            }        }    }}
启动/usr/local/openresty/nginx/sbin/nginx -p `pwd` -c conf/nginx_openresty_02.conf测试curl -i http://127.0.0.1/lua_1curl -i http://127.0.0.1/lua_1
3. 带参数示例
user www-data;worker_processes auto;pid /run/nginx.pid;error_log logs/error.log;events {    worker_connections 1024;}http {    server {        listen 8080;        location /lua_1 {            default_type text/html;            content_by_lua_block {                ngx.say(ngx.var.arg_a)            }        }    }}
启动/usr/local/openresty/nginx/sbin/nginx -p `pwd` -c conf/nginx_openresty_03.conf测试curl -i http://127.0.0.1?a=nginx_lua

8. OpenResty 连接 redis


配置文件
user www-data;worker_processes auto;pid /run/nginx.pid;error_log logs/error.log;events {    worker_connections 1024;}http {    server {        listen 8080;        location ~/redis_lua/(\d+)$ {            default_type text/html;            charset utf-8;            lua_code_cache on;            content_by_lua_file '/home/zp/openresty/lua/redis.lua';        }    }}
lua 脚本
local json = require("cjson")local redis = require("resty.redis")local red = redis:new()red:set_timeout(1000)local ip = "127.0.0.1"local port = 6379local ok, err = red:connect(ip, port)if not ok then    ngx.say('connect to redis error: ', err)    return ngx.exit(500)endlocal id = ngx.var[1]local value = "calue-"..idred:set(id, value)local resp, err = red:get(id)if not resp then    ngx.say('get from redis error: ', err)    return ngx.exit(500)endred:close()ngx.say(json.encode({content=resp}))
测试
启动/usr/local/openresty/nginx/sbin/nginx -p `pwd` -c conf/nginx_openresty_04.conf测试curl -i http://127.0.0.1/redis_lua/1curl -i http://127.0.0.1/redis_lua/2curl -i http://127.0.0.1/redis_lua/3

感谢各位的阅读,以上就是"如何通过 Lua 扩展 Nginx"的内容了,经过本文的学习后,相信大家对如何通过 Lua 扩展 Nginx这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

阶段 处理 进程 模块 线程 配置 内容 指令 运行 多个 模型 测试 开发 控制 检查 服务 权限 阻塞 复杂 重要 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海挚品互联网科技有限公司 华服互联网科技怎么样 中关村互联网 科技集团 互联网科技巨头监管 科技企业和互联网企业 互联网金融 科技 撒么互联网科技公司 互联网系的金融科技公司 厦门比较好的科技互联网公司 华夏互联网科技业 互联网科技和信息 互联网科技和法律行业 互联网科技的全部知识 无锡工业互联网科技有限公司 南通创西澳互联网科技有限公司 宇信科技在杭州互联网排第几 半导体行业属于互联网高科技类吗 山东大美朱楼互联网科技有限公司 知域互联网科技有限公司官网 中国主要互联网科技公司 山东特亿宝互联网科技有限公司 互联网科技logo设计 隆华科技工业互联网 宁夏众和广鑫互联网科技有限公司 恒生互联网科技指数跳水 工业互联网展湾科技股份有限公司 黑科技 体验场景 互联网大会 山东大美朱楼互联网科技有限公司 国产互联网科技公司 承德科技产业互联网平台
0