OpenResty为什么选择Lua
最近研究Kong和apisix,他们2个居然都用OpenResty,于是我决定研究下
什么是 OpenResty ?
openResty是一个基于Nginx与LuaJIT的高性能WEB平台。它在Nginx基础上集成了LuaJIT虚拟机及一系列高质量第三方Nginx模块,让开发者能用 Lua 脚本直接在Nginx 内部编写业务逻辑,把Nginx从单纯的静态反向代理升级为可编译的web应用服务或动态网关。保留了Nginx强大的性能同时又增强了适配业务的灵活性。OpenResty 是一个整合的平台;
下面是OpenResty 和Nginx,Lua 之间的关系;
┌─────────────────────────────────────────────┐ │ OpenResty │ │ ┌─────────────────────────────────────┐ │ │ │ Nginx │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ ngx_lua 模块 │ │ │ │ │ │ ┌─────────────────────┐ │ │ │ │ │ │ │ LuaJIT │ │ │ │ │ │ │ │ ┌─────────────┐ │ │ │ │ │ │ │ │ │ Lua代码 │ │ │ │ │ │ │ │ │ └─────────────┘ │ │ │ │ │ │ │ └─────────────────────┘ │ │ │ │ │ └─────────────────────────────┘ │ │ │ └─────────────────────────────────────┘ │ └─────────────────────────────────────────────┘什么是Lua ?
Lua 是一门轻量级,可嵌入的脚本语言,设计的目的就是-好嵌入到别的程序里当胶水语言。它语法简单,运行快,体积小,在很多软件里都充当内置脚本引擎的角色。
1.极轻量
整个解释器编译完才1-200KB
源码也好集成进C/C++项目,所以很多游戏引擎,嵌入式设备都用它
2.语法简洁但够用,入门门槛低,很容易上手
3.结构简单但灵活
Lua只有一种复合数据结构-table,但它既能当数组用,又能当字典/对象用,非常灵活
4.与C/C++完美融合
Lua 的作者说过一句话:“Lua 不是一个独立的语言,而是一个库。”
Lua的ffi可以直接调用C
5.速度快
虽然是解释语言,但是LuaJIT让热点代码直接编译成本地机器码,性能接近C
为什么偏偏是Lua?
从lua的介绍就能看出来
1.Lua体积小
2.速度快
3.学习成本低
4.与C完美兼容
| 特性 | Lua | Python | JS/V8 | Go | PHP |
|---|---|---|---|---|---|
| 极小嵌入体积 | ✅ | ❌ | ❌ | ❌ | ❌ |
| 原生协程 | ✅ | ⚠️ async/await 非真协程 | ❌ generator 不等同协程 | ✅ goroutine 但调度独立 | ❌ |
| C 嵌入友好 | ✅ | ❌ C API 复杂且GIL受限 | ❌ V8 API 重型且迭代快 | ⚠️ CGO 有调用开销 | ❌ |
| 高性能 JIT | ✅ LuaJIT | ⚠️ PyPy 难嵌入生产 | ✅ V8 强但内存占用大 | ✅ 编译为机器码(AOT) | ❌ |
| FFI 直接调 C | ✅ LuaJIT FFI 零开销 | ⚠️ ctypes 慢 | ❌ 无原生FFI | ⚠️ CGO 跨边界有损耗 | ❌ |
| 热加载 | ✅package.loaded清除即生效 | ✅ 重载模块可行 | ✅ 模块缓存可清 | ❌ 需重新编译 | ✅ opcache 重置 |
核心架构
OpenResty 的架构可以分为三层:
1.宿主(host):增强版的Nginx内核,提供基于 epoll/kqueue的事件驱动,非阻塞I/O 模型,以及 Master-worker 进程管理。
2.引擎(Engine): LuaJIT 即时编译器,执行效率极高,提供Lua协程支持,可通过FFI直接调用C函数。
3.桥梁(Bridge):ngx_lua_module,将Lua解释器嵌入Nginx 的worker进程中,允许在不同请求处理阶段注入Lua代码。
