简介
Nginx 的高性能是业界公认的,近年来在全球服务器市场上的占比份额也在逐年增加,在国内知名互联网公司也有广泛的应用,阿里还基于Nginx进行扩展打造了著名的Tengine。而OpenResty是由国人章亦春基于Nginx和LuaJIT打造的动态web平台,LuaJIT是Lua编程语言的即时编译器。Lua是一种强大、动态、轻量级的编程语言。该语言的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能,OpenResty就是通过使用Lua来扩展Nginx来实现的可扩展Web平台。目前OpenResty 大多用在 API 网关的开发中,当然也可以用来替代Nginx,用于反向代理和负载均衡的场景。
OpenResty 的架构组成

如前所述,OpenResty 底层是基于Nginx 和 LuaJIT 的,所以 OpenResty 继承了 Nginx 的多进程架构, 每一个 Worker 进程都是 fork Master 进程而得到的, 其实, Master 进程中的 LuaJIT 虚拟机也会一起 fork 过来。在同一个 Worker 内的所有协程,都会共享这个 LuaJIT 虚拟机,Lua 代码的执行也是在这个虚拟机中完成的。而在同一个时间点上,每个 Worker 进程只能处理一个用户的请求,也就是只有一个协程在运行。
Nginx
由于 Nginx 处理请求采用的是事件驱动模型,所以每一个 Worker进程最好独占一个CPU。实践中我们往往把 Worker 进程的数量配置成与CPU核数相同,此外把每一个 Worker 进程与某一个CPU核绑定在一起,这样可以更好的使用每一个CPU核上的CPU缓存,减少缓存失效的命中率,进而提高请求处理的性能。
LuaJIT
其实 OpenResty 最初默认使用的是标准Lua,从 1.5.8.1 版本开始才默认使用 LuaJIT,背后的原因是因为 LuaJIT 相比标准Lua有很大的性能优势。
首先,LuaJIT 的运行时环境除了一个汇编实现的 Lua 解释器外,还有一个可以直接生成机器代码的 JIT 编译器。开始的时候,LuaJIT 和标准 Lua 一样,Lua 代码被编译为字节码,字节码被 LuaJIT 的解释器解释执行。但不同的是,LuaJIT 的解释器会在执行字节码的同时,记录一些运行时的统计信息,比如每个 Lua 函数调用入口的实际运行次数,还有每个 Lua 循环的实际执行次数。当这些次数超过某个随机的阈值时,便认为对应的 Lua 函数入口或者对应的 Lua 循环足够热,这时便会触发 JIT 编译器开始工作。JIT 编译器会从热函数的入口或者热循环的某个位置开始,尝试编译对应的 Lua 代码路径。编译的过程,是把 LuaJIT 字节码先转换成 LuaJIT 自己定义的中间码(IR),然后再生成目标机器的机器码。这个过程跟Java中JIT编译器工作原理类似,其实它们都是为了提高程序运行效率而采取的同一类优化手段,正所谓底层

本文详细介绍了OpenResty基于Nginx和LuaJIT的架构,探讨其工作原理,涵盖了从配置到API调用的各个环节,并通过实例演示了如何快速入门。了解OpenResty在得物的技术应用,以及其在负载均衡和API网关开发中的关键作用。
最低0.47元/天 解锁文章
569

被折叠的 条评论
为什么被折叠?



