Fork me on GitHub

OpenResty简介及原理

目录

  • 背景

  • 第一部分 su命令

  • 第二部分 susu -区别

  • 参考文献及资料

背景

Nginx有很多的特性和好处,但是在Nginx上开发成了一个难题,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开发者对其望而生畏。为了开发人员方便,所以有了一种整合了Nginx和lua的框架,那就是OpenResty,它帮我们实现了可以用lua的规范开发,随着系统架构的不断升级、优化,OpenResty在被广泛的应用。

2.OpenResty概念

OpenResty(又称:ngx_openresty)是一个基于Nginx的可伸缩的Web平台,由中国人章亦春发起,提供了很多高质量的第三方模块。

OpenResty是一个强大的Web应用服务器,Web开发人员可以使用lua脚本语言调动Nginx支持的各种C以及Lua模块,更主要的是在性能方面,OpenResty可以快速的构造出足以胜任10K以上的并发连接响应的超高性能的Web应用系统。

二.OpenResty的运行原理

Nginx 采用的是 master-worker 模型,一个 master 进程管理多个 worker 进程,基本的事件处理都是放在 woker 中,master 负责一些全局初始化,以及对 worker 的管理。

OpenResty中,每个worker进程使用一个LuaVM,当请求被分配到worker时,将在这个LuaVM中创建一个coroutine协程,协程之间数据隔离,每个协程都具有独立的全局变量。

img

协程和多线程下的线程类似:有自己的堆栈,自己的局部变量,有自己的指令指针,但是和其他协程程序共享全局变量等信息。线程和协程的主要不同在于:多处理器的情况下,概念上来说多线程是同时运行多个线程,而协程是通过代码来完成协程的切换,任何时刻只有一个协程程序在运行。并且这个在运行的协程只有明确被要求挂起时才会被挂起
OpenResty处理请求流程
Nginx会把一个请求分成不同阶段,第三方模块可以根据自己的行为,挂在到不同阶段中以达到自身目的。OpenResty采用了同样的特性,不同阶段有着不同的处理行为。

三.OpenResty的优势

首先我们选择使用OpenResty,其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。
借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。
OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒杀、动态服务、单品页、列表页等都在使用Nginx+Lua架构,其他公司如淘宝、去哪儿网等。

四.OpenResty的nginx架构的特点

Nginx采用多进程模式,对于每个worker进程都是独立的,因此不需要加锁,所以节省了锁带来的性能开销。采用独立的进程的好处在于worker进程之间相互不会影响,当一个进程退出后,其他进程依然工作,以保证服务不会终端。
Nginx采用异步非堵塞的方式去处理请求,异步非堵塞就是当一个线程调用出现阻塞而等待时,其他线程可以去处理其他任务。

多阶段处理

基于 Nginx 使用的多模块设计思想,Nginx 将HTTP请求的处理过程划分为多个阶段。这样可以使一个HTTP请求的处理过程由很多模块参与处理,每个模块只专注于一个独立而简单的功能处理,可以使性能更好、更稳定,同时拥有更好的扩展性。

OpenResty在HTTP处理阶段基础上分别在Rewrite/Access阶段、Content阶段、Log阶段注册了自己的handler,加上系统初始阶段master的两个阶段,共11个阶段为Lua脚本提供处理介入的能力。下图描述了OpenResty可以使用的主要阶段:

https://res.cloudinary.com/practicaldev/image/fetch/s--7aySW_GE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1005/1%2AgfAT3GULg89r8MivUVCjQg.jpeg

OpenResty将我们编写的Lua代码挂载到不同阶段进行处理,每个阶段分工明确,代码独立。

init_by_lua*:Master进程加载 Nginx 配置文件时运行,一般用来注册全局变量或者预加载Lua模块。

init_worker_by_lua*:每个worker进程启动时执行,通常用于定时拉取配置/数据或者进行后端服务的健康检查。

set_by_lua*:变量初始化。

rewrite_by_lua*:可以实现复杂的转发、重定向逻辑。

access_by_lua*:IP准入、接口权限等情况集中处理。

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

header_filter_by_lua*:响应头部或者cookie处理。

body_filter_by_lua*:对响应数据进行过滤,如截断或者替换。

log_by_lua*:会话完成后,本地异步完成日志记录。

五.Lua及其ngx_lua简介

1.Lua

Lua 是一个小巧的脚本语言。作者是巴西人。该语言的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能
Lua的特点:
Lua脚本可以很容易的被C/C++代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,Ini等文件格式,并且更容易理解和维护。
Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的Lua解释器不过200k,在目前所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。

2.ngx_lua

ngx_lua是将Lua嵌入Nginx,让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求。Lua内建协程,可以很好的将异步回调转换成顺序调用的形式。ngx_lua在Lua中进行的IO操作都会委托给Nginx的事件模型,从而实现非阻塞调用。开发者可以采用串行的方式编写程序,ngx_lua会自动的在进行阻塞的IO操作中终端,保存上下文,然后将IO操作委托给Nginx事件处理机制,在IO操作完成后,ngx_lua会恢复上下文,程序继续执行,这些操作都是对用户程序透明的。
每个Nginx的worker进程持有一个Lua解释器或LuaJIT实例,被这个worker处理的所有请求共享这个实例。每个请求的context上下文会被Lua轻量级的协程分隔,从而保证各个请求时独立的。

3.ngx_lua模块的原理

每个工作进程worker创建一个Lua虚拟机(LuaVM),工作进程worker内部协议共享VM。
每个Nginx I/O原语封装后注入Lua虚拟机,并允许Lua代码直接访问。
每个外部请求都由一个Lua协程处理,协程之间数据隔离
Lua代码调用I/O操作等异步时,会挂起当前协程,而不阻塞工作机进程。
I/O等异步操作完成时,还原相关协程相关协议的上下文,并继续运行。

https://blog.csdn.net/even160941/article/details/97308725

参考文献及资料

1、OpenResty 作者章亦春访谈实录,链接:https://www.cnblogs.com/zampo/p/4269147.html

本文标题:OpenResty简介及原理

文章作者:rong xiang

发布时间:2021年06月14日 - 12:06

最后更新:2022年10月25日 - 23:10

原始链接:https://zjrongxiang.github.io/posts/9c476ab0/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%