lua为什么喜欢和nginx一起做鉴权等业务呢?
因为nginx本身高性能,而且nginx worker采用c语言编写,可以高性能的执行小部分业务逻辑(主要是对本地缓存做业务逻辑)。但是nginx基于c的插件拓展口不大友好。而lua作为一种语法糖,恰好可以弥补这个缺点。
我们可以利用Lua语法编写nginx插件,让部分业务在nginx运行(反正nginx运行那么快,找点小业务拖一拖它的性能一点都不过分,据说Nginx单机压测能到3万tps。)
lua可以做一些针对request请求包的安全检测,甚至可以通过读取restful接口实现存储功能。
所以lua可以做的业务逻辑还挺多的。
其他的话,就是程序员学习成本了,据说大部分后端程序员都能在1~2周就能写出高质量的lua业务接口。还有就是 社区以及类库丰富等优势…本身还是看业务的量以及团队技术背景。
当然如果本身后端框架,像Java这种有很好并发性能的,就没必要多维护一个节点了。(遵守 奥卡姆定律)
OpenResty
说到nginx+lua,最著名的实现就是 OpenResty
nginx的架构是一个master进程 fork 创建多个worker进程,用来处理请求, master对IO进行 epoll 复用。
worker子进程受 master进程管理。
(fork函数最好了解一下,尤其是共享父进程文件句柄这个特点。)
而 OpenResty 则是利用nginx提供的模块扩展,在nginx master进程启动的时候拉起一个 LuaJT VM.他是一个lua虚拟机进程。
之后fork 的时候,每一个worker也会创建 LuaJT VM, 而真正执行lua业务代码的,也正式这些 worker LuaJT VM 进程。
这个之后相对 LuaJT VM 来说, worker就是等于VM 客户端的角色,利用VM Client接口发送 Lua脚本命令给VM。
而 在VM里面执行业务的是协程 coroutine (co-routine)。
什么是协程呢?
我们可以认为它就是线程,一样拥有本地方法栈,且拥有访问全局变量的权限。对我们用户来说跟线程用法没啥差别。
但是它的实现却和线程不一样,线程的调度算法是在内核实现(具体了解操作系统的线程模型)。
而协程的调度算法是在用户空间实现,这使得多个协程无法在多CPU的环境下实现并行。
换句话说,同一时间,CPU只会执行一个协程。对于用户来说它就是并发的了(不是并行)。最为有趣的是,协程的上下文切换经常是手工完成的。哈哈哈哈哈哈
协程的状态为依次:running 运行,suspend挂起, dead 死亡。