15 | OpenResty 和别的开发平台有什么不同?
温铭
该思维导图由 AI 生成,仅供参考
你好,我是温铭。
上一模块中, 你已经学习了 OpenResty 的两个基石:NGINX 和 LuaJIT,相信你已经摩拳擦掌,准备开始学习 OpenResty 提供的 API 了吧?
不过,别着急,在这之前,你还需要再花一点儿时间,来熟悉下 OpenResty 的原理和基本概念。
原理
在前面的 LuaJIT 内容中,你已经见过下面这个架构图:
这里我再详细解释一下。
OpenResty 的 master 和 worker 进程中,都包含一个 LuaJIT VM。在同一个进程内的所有协程,都会共享这个 VM,并在这个 VM 中运行 Lua 代码。
而在同一个时间点上,每个 worker 进程只能处理一个用户的请求,也就是只有一个协程在运行。看到这里,你可能会有一个疑问:NGINX 既然能够支持 C10K (上万并发),不是需要同时处理一万个请求吗?
当然不是,NGINX 实际上是通过 epoll 的事件驱动,来减少等待和空转,才尽可能地让 CPU 资源都用于处理用户的请求。毕竟,只有单个的请求被足够快地处理完,整体才能达到高性能的目的。如果采用的是多线程模式,让一个请求对应一个线程,那么在 C10K 的情况下,资源很容易就会被耗尽的。
在 OpenResty 层面,Lua 的协程会与 NGINX 的事件机制相互配合。如果 Lua 代码中出现类似查询 MySQL 数据库这样的 I/O 操作,就会先调用 Lua 协程的 yield 把自己挂起,然后在 NGINX 中注册回调;在 I/O 操作完成(也可能是超时或者出错)后,再由 NGINX 回调 resume 来唤醒 Lua 协程。这样就完成了 Lua 协程和 NGINX 事件驱动的配合,避免在 Lua 代码中写回调。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
OpenResty 是一个基于 NGINX 和 LuaJIT 的开发平台,通过与 NGINX 的协同工作,实现了高性能的特点。该平台提供了丰富的 API 和灵活的阶段概念,使得开发者能够更好地利用其特性进行开发。文章首先介绍了 OpenResty 的原理,包括 LuaJIT VM 在 master 和 worker 进程中的运行机制,以及 Lua 协程与 NGINX 事件驱动的配合。其次,文章提到了 OpenResty 中的阶段概念和非阻塞特点,强调了其提供的 API 都是非阻塞的,并且每个 API 都有特定的使用阶段限制。最后,通过具体的示例说明了如何使用 `ngx.sleep` 实现非阻塞的等待操作。此外,文章还涉及了变量的生命周期和模块变量的特性,以及跨阶段的变量处理方式,如使用 `ngx.ctx` 存储基于请求的 Lua 数据。总的来说,OpenResty 通过与 NGINX 的协同工作,实现了高性能的特点,同时提供了丰富的 API 和灵活的阶段概念,使得开发者能够更好地利用其特性进行开发。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《OpenResty 从入门到实战》,新⼈⾸单¥59
《OpenResty 从入门到实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(15)
- 最新
- 精选
- jackstraw老师说的,“访问模块变量的时候,你最好保持只读,而不要尝试去修改,不然在高并发的情况下会出现 race”这个问题有点疑惑。既然每个worker同一时间只会有一个请求在进行中,那么同一时间只会有一个请求正在操作这个模块变量啊?怎么会出现race?
作者回复: 如果修改的中途有 yield 操作,就可能会有 race。没有 yield 的话自然没有。
2019-08-1235 - 宝仔location配置如下: location / { access_by_lua_file lua/access.lua; content_by_lua_file lua/content.lua; } access_by_lua_file内容如下: ngx.var.res = "test" content_by_lua_file内容如下: ngx.say(ngx.var.res) 老师你好,这样子也说可以做到变量跨阶段读写的
作者回复: 是的
2019-09-051 - FF温老师能否针对 OR 进程和协程的交互和他俩的协作关系展开讲讲。 比如在同一个时间点上,每个 worker 进程只能处理一个用户的请求,也就是只有一个协程在运行。那如果协程阻塞,这个 worker 进程是否也在阻塞状态 ?协程是不是由 OR 的 worker 进程来创建 ,单个请求完后就消亡 ? 或者这方面有什么资料可以推荐下吗? 感谢。盼复。
作者回复: 其实不是只有一个协程,是有一个父协程和子协程。这方面推荐 codedump 老师的源码分析:https://www.codedump.info/post/20190501-lua-stream/,内容质量很高
2019-07-011 - life_牛老师,编译openresty时候出现 error SSE 4.2 not found这个错误,网上有说cpu太老 如何处理这样的问题,还是可以忽略
作者回复: OpenResty 的一些特性用到了 SSE 4.2 指令集,这个只能换机器了
2019-09-122 - 上善若水老师您好,看你的最佳实践中,遇到一个问题请教一下,在引入第三方resty库时,我根据配置请求不是返回的百度首页,是一个 <!DOCTYPE html> <!--STATUS OK--> 是什么问题?多谢。
作者回复: 是否有更详细的信息?可以放到 gist 里面
2019-07-02 - helloworld说一段比较绕口的废话来理解协程、异步: openresty中的一个worker进程中只有一个线程,该线程是轻量化的线程,也可以叫微线程,也可以称为协程,所谓协程就是处理协程对象的线程,所谓协程对象就是异步化的代码片段,所谓异步化就是遇到网络I/O磁盘I/O等耗时I/O操作时使CPU停止等待I/O,马上去处理下一个协程对象,避免白白浪费CPU时间,这就是非阻塞,具体说应该叫CPU非阻塞,当之前的协程对象I/O完成后,CPU在回去继续处理该协程对象剩余的代码,当然了继续处理过程中遇到I/O阻塞还会继续中断跳出去执行其他协程对象,往复...2019-06-289
- 阳光梦老师,基于worker的缓存模块,对数据改写操作时候也有竞争?2019-06-2823
- DCopenresty的日志路径是如何配置的,这个问题一直困扰我,ngx.log打印不同级别的日志,文件位置可以配置吗,默认是error.log吗2021-03-151
- ꧁༺༻꧂温大,请教个问题,我运行实例,require("hello") 提示找不到,错误信息如下: /home/jin/geektime/lua/import.lua:1: module 'data' not found: no field package.preload['data'] no file '/usr/local/openresty/site/lualib/data.ljbc' no file '/usr/local/openresty/site/lualib/data/init.ljbc' no file '/usr/local/openresty/lualib/data.ljbc' no file '/usr/local/openresty/lualib/data/init.ljbc' no file '/usr/local/openresty/site/lualib/data.lua' no file '/usr/local/openresty/site/lualib/data/init.lua' no file '/usr/local/openresty/lualib/data.lua' no file '/usr/local/openresty/lualib/data/init.lua' no file './data.lua' no file '/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/data.lua' no file '/usr/local/share/lua/5.1/data.lua' no file '/usr/local/share/lua/5.1/data/init.lua' no file '/usr/local/openresty/luajit/share/lua/5.1/data.lua' no file '/usr/local/openresty/luajit/share/lua/5.1/data/init.lua' no file '/usr/local/openresty/site/lualib/data.so' no file '/usr/local/openresty/lualib/data.so' no file './data.so' no file '/usr/local/lib/lua/5.1/data.so' no file '/usr/local/openresty/luajit/lib/lua/5.1/data.so' no file '/usr/local/lib/lua/5.1/loadall.so' stack traceback: coroutine 0: [C]: in function 'require' /home/jin/geektime/lua/import.lua:1: in main chunk, client: 127.0.0.1, server: , request: "GET /import HTTP/1.1", host: "127.0.0.1:8080" 但是 "./data.lua" 明明是存在的 -------- $ cat lua/data.lua local _M = {} _M.color = { red = 1, blue = 2, green = 3 } return _M ------ $ cat lua/import.lua local hello = require ("data") ngx.say(hello.color.green) ------ $ cat conf/nginx.conf ...... location /import { content_by_lua_file lua/import.lua; } ....2022-12-09归属地:四川1
- 猪小擎同步和异步,阻塞和非阻塞,这都是没有好和坏的区别的,以为异步非阻塞比同步阻塞好,很片面,而且不对。如果硬要说阻塞和非阻塞哪个更好一点,应该是阻塞比非阻塞更好一点。用一个cpu空转的代码来做阻塞的例子,这也太黑阻塞了吧。空转不等于阻塞,空转用100%CPU,阻塞不消耗CPU。2022-04-06
收起评论