news 2026/4/18 11:52:25

Openresty基础知识详解:轻松驾驭高性能web网关

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Openresty基础知识详解:轻松驾驭高性能web网关

nginx 采用模块化设计,使得每一个 http 模块可以仅专注于完成一个独立的、简单的功能,而一个请求的完整处理过程可以由无数个 http 模块共同合作完成。为了灵活有效地指定下一个http 处理模块是哪一个;http 框架依据常见的的处理流程将处理阶段划分为 11 个阶段,其中每一个阶段都可以由任意多个http 模块流水式地处理请求。

openresty 将 lua 脚本嵌入到 nginx 阶段处理的末尾模块下;这样以来并不会影响 nginx 原有的功能,而是在 nginx 基础上丰富它的功能。

嵌入 lua 的优点是:使用 openresty 开发,不需要重新编译,直接修改 lua 脚本,重新启动即可。

抽象:虚拟主机对应一个lua虚拟机,每个请求对应一个协程。

Lua 模块指令顺序:

交互流程:

Lua嵌入nginx:

(1)init_by_lua。master fork之前调用,此阶段初始化的数据将被复制多个worker进程中。它的作用有:加载一些耗时模块、设置全局变量、初始化共享内存等。在 nginx 重新加载配置文件时,运行里面 lua 脚本,常用于全局变量的申请。例如 lua_shared_dict 共享内存的申请,只有当 nginx 重启后,共享内存数据才清空,这常用于统计。

(2)init_worker_by_lua。master fork之后,worker初始化时调用,在每个 Nginx 工作进程启动时执行;此阶段初始化的数据各个worker可不同。它很重要的一个作用是开启定时器。

(3)ssl_certificate_by_lua。ssl阶段,在握手时设置安全证书。

(4)set_by_lua。用于设置nginx变量;设置一个变量,常用与计算一个逻辑,然后返回结果,该阶段不能运行Output API、Control API、Subrequest API、Cosocket API。

(5)rewrite_by_lua。用于执行内部url重写或外部重定向。在 access 阶段前运行,主要用于 rewrite url。

(6)access_by_lua。用于访问控制。这条指令运行于 nginx access 阶段的末尾,因此总是在 allow 和 deny 这样的指令之后运行,它们同属 access 阶段。可用来判断请求是否具备访问权限。

(7)content_by_lua。用于内容管理。此阶段是所有请求处理阶段中最为重要的一个,运行在这个阶段的配置指令一般都肩负着生成内容(content)并输出HTTP 响应。

(8)header_filter_by_lua。设置应答消息的头部信息;一般只用于设置 Cookie 和 Headers 等。

(9)body_filter_by_lua。用于修改应答body的内容。一般会在一次请求中被调用多次,因为这是实现基于 HTTP 1.1 chunked 编码的所谓“流式输出”的。

(10)log_by_lua。用于log请求处理阶段,用lua处理日志。该阶段总是运行在请求结束的时候,用于请求的后续操作,如在共享内存中进行统计数据,如果要高精确的数据统计,应该使用 body_filter_by_lua

(11)balancer_by_lua。上游服务器的负载均衡。

四、责任链

责任链模式是一种行为型设计模式,多个对象都有机会处理请求,避免请求的发送者和接收者之间产生紧密的耦合关系。在该模式中,请求的接收者被组织成一个处理对象链表,请求沿着这个链条传递,直到链中某个对象对其进行处理。

OpenResty 中,Nginx 的请求处理阶段天然体现出责任链模式。每个 Nginx 阶段都可以看作链中的一个“处理者”,lua-nginx-module在这些预设的处理阶段中插入自定义的 Lua 逻辑。OpenResty 通过ngx.exit()函数提供对责任链流程的精细控制:

  • ngx.exit(ngx.OK)ngx.exit(ngx.DECLINED): 表示当前阶段的处理已完成,请求将继续流转到 Nginx 处理链的下一个阶段。

  • ngx.exit(HTTP_STATUS_CODE)(例如ngx.exit(200),ngx.exit(403),ngx.exit(500)): 表示当前请求的处理已结束,Nginx 将立即发送相应的 HTTP 状态码和响应体,并终止后续所有阶段的处理。这使得 Lua 脚本能够根据业务逻辑随时中断请求处理,例如在认证失败时直接返回 403 错误。

按需在处理链的任何环节进行干预,实现灵活的请求处理流程控制。

五、cosocket

cosocket是 OpenResty 为 Nginx 引入的最核心、最具革命性的功能之一让Lua 脚本能够在不阻塞 Nginx Worker 进程的前提下,进行网络 I/O 操作,在 HTTP 请求处理过程中无缝地访问各种第三方服务。

cosocket的实现原理结合了 Nginx 的事件驱动机制和 Lua 的协程 (coroutine) 特性,实现了非阻塞的网络 I/O。以同步的代码风格编写异步的网络操作,简化复杂异步编程的难度。

引入cosocket后,单线程的 Nginx Worker 进程内部相当于拥有了多条“并行”的同步逻辑线(即 Lua 协程)。一个 Lua 协程发起网络 I/O 请求,如果数据尚未就绪,协程会主动让出 CPU 控制权,把 I/O 操作注册到 Nginx 的事件循环中,并进入挂起状态。Nginx Worker 进程则继续处理其他请求或唤醒其他已就绪的协程。一旦 I/O 事件完成,Nginx 的事件循环会唤醒之前挂起的 Lua 协程,使其从上次中断的地方继续执行。这种“让出”和“唤醒”的机制,确保Nginx Worker 进程始终保持非阻塞,处理大量并发连接。

通过 Lua 协程把底层 Socket 的异步事件编程转化为上层同步处理的编码体验,cosocket提升了 OpenResty 的开发效率和性能。基于cosocket,OpenResty 社区和官方开发了大量高质量的第三方库:

  • ngx.socket.tcp: 用于通用的 TCP 客户端通信。

  • ngx.socket.udp: 用于通用的 UDP 客户端通信。

  • resty.redis: 高性能 Redis 客户端库。

  • resty.mysql: 高性能 MySQL 客户端库。

  • resty.postgres: 高性能 PostgreSQL 客户端库。

  • resty.memcached: 高性能 Memcached 客户端库。

  • resty.http: 高性能 HTTP/HTTPS 客户端库。

  • resty.kafka: Kafka 客户端库。

  • 等等。

这些库让 OpenResty 集成和访问各种外部服务变得异常简单。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 19:51:23

考研408--组成原理--day7--指令扩展操作码寻址

(以下内容全部来自上述课程) 目录指令格式1. 指令的定义2. 指令的分类2.1 按地址码数目分类2.2 按指令长度分类2.3 按操作码长度分类2.4 按操作类型分类3. 小结扩展操作码指令寻址1. 提出问题2. 顺序寻址2.1 按字编址--定长2.2 按字节编址--定长2.3 按字…

作者头像 李华
网站建设 2026/4/18 7:33:07

C语言实现队列(附带源码)

一、项目背景详细介绍队列(Queue)是计算机科学中最基础、最重要的数据结构之一,属于线性结构。它采用 先进先出(FIFO:First In First Out) 的原则,广泛用于实际系统中,例如&#xff…

作者头像 李华
网站建设 2026/4/18 9:05:00

百度网盘高速下载优化方案:重新定义文件传输效率

百度网盘高速下载优化方案:重新定义文件传输效率 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 基于提供的百度网盘下载工具文章,请创作一篇结构新颖、…

作者头像 李华
网站建设 2026/4/18 9:06:07

自建项目管理平台:用 Focalboard+cpolar 打破协作边界

文章目录前言1. 使用Docker本地部署Focalboard1.1 在Windows中安装 Docker1.2 使用Docker部署Focalboard2. 安装Cpolar内网穿透工具3. 实现公网访问Focalboard4. 固定Focalboard公网地址前言 Focalboard 是一款开源的项目管理工具,核心功能围绕看板协作展开&#x…

作者头像 李华