OpenResty从入门到实战
温铭
OpenResty软件基金会主席,《OpenResty 最佳实践》作者
立即订阅
4332 人已学习
课程目录
已完结 52 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | OpenResty,为你打开高性能开发的大门
免费
入门篇 (14讲)
01 | 初探OpenResty的三大特性
02 | 如何写出你的“hello world”?
03 | 揪出隐藏在背后的那些子项目
04 | 如何管理第三方包?从包管理工具luarocks和opm说起
05 | [视频]opm项目导读
06 | OpenResty 中用到的 NGINX 知识
07 | 带你快速上手 Lua
08 | LuaJIT分支和标准Lua有什么不同?
09 | 为什么 lua-resty-core 性能更高一些?
10 | JIT编译器的死穴:为什么要避免使用 NYI ?
11 | 剖析Lua唯一的数据结构table和metatable特性
12 | 高手秘诀:识别Lua的独有概念和坑
13 | [视频]实战:基于FFI实现的lua-resty-lrucache
14 | 答疑(一):Lua 规则和 NGINX 配置文件产生冲突怎么办?
API篇 (11讲)
15 | OpenResty 和别的开发平台有什么不同?
16 | 秒杀大多数开发问题的两个利器:文档和测试案例
17 | 为什么能成为更好的Web服务器?动态处理请求和响应是关键
18 | worker间的通信法宝:最重要的数据结构之shared dict
19 | OpenResty 的核心和精髓:cosocket
20 | 超越 Web 服务器:特权进程和定时任务
21 | 带你玩转时间、正则表达式等常用API
22 | [视频]从一个安全漏洞说起,探寻API性能和安全的平衡
23 | [视频]导读lua-resty-requests:优秀的lua-resty-*是如何编写的?
24 | 实战:处理四层流量,实现Memcached Server
25 | 答疑(二):特权进程的权限到底是什么?
测试篇 (5讲)
26 | 代码贡献者的拦路虎:test::nginx 简介
27 | test::nginx 包罗万象的测试方法
28 | test::nginx 还可以这样用?
29 | 最容易失准的性能测试?你需要压测工具界的“悍马”wrk
30 | 答疑(三)如何搭建测试的网络结构?
性能优化篇 (16讲)
31 | 性能下降10倍的真凶:阻塞函数
32 | 让人又恨又爱的字符串操作
33 | 性能提升10倍的秘诀:必须用好 table
34 | 特别放送:OpenResty编码指南
35 | [视频]实际项目中的性能优化:ingress-nginx中的几个PR解读
36 | 盘点OpenResty的各种调试手段
37 | systemtap-toolkit和stapxx:如何用数据搞定“疑难杂症”?
38 | [视频]巧用wrk和火焰图,科学定位性能瓶颈
39 | 高性能的关键:shared dict 缓存和 lru 缓存
40 | 缓存与风暴并存,谁说缓存风暴不可避免?
41 | lua-resty-* 封装,让你远离多级缓存之痛
42 | 如何应对突发流量:漏桶和令牌桶的概念
43 | 灵活实现动态限流限速,其实没有那么难
44 | OpenResty 的杀手锏:动态
45 | 不得不提的能力外延:OpenResty常用的第三方库
46 | 答疑(四):共享字典的缓存是必须的吗?
API网关篇 (4讲)
47 | 微服务API网关搭建三步曲(一)
48 | 微服务API网关搭建三步曲(二)
49 | 微服务API网关搭建三步曲(三)
50 | 答疑(五):如何在工作中引入 OpenResty?
结束语 (1讲)
结束语 | 行百里者半九十
OpenResty从入门到实战
登录|注册

10 | JIT编译器的死穴:为什么要避免使用 NYI ?

温铭 2019-06-17
你好,我是温铭。
上一节,我们一起了解了 LuaJIT 中的 FFI。如果你的项目中只用到了 OpenResty 提供的 API,没有自己调用 C 函数的需求,那么 FFI 对你而言并没有那么重要,你只需要确保开启了 lua-resty-core 即可。
但我们今天要讲的 LuaJIT 中 NYI,却是每一个使用 OpenResty 的工程师都逃避不了的关键问题,它对于性能的影响举足轻重。
你可以很快使用 OpenResty 写出逻辑正确的代码,但不明白 NYI,你就不能写出高效的代码,无法发挥 OpenResty 真正的威力。这两者的性能差距,至少是一个数量级的。

什么是 NYI?

那究竟什么是 NYI 呢?先回顾下我们之前提到过的一个知识点:
LuaJIT 的运行时环境,除了一个汇编实现的 Lua 解释器外,还有一个可以直接生成机器代码的 JIT 编译器。
LuaJIT 中 JIT 编译器的实现还不完善,有一些原语它还无法编译,因为这些原语实现起来比较困难,再加上 LuaJIT 的作者目前处于半退休状态。这些原语包括常见的 pairs() 函数、unpack() 函数、基于 Lua CFunction 实现的 Lua C 模块等。这样一来,当 JIT 编译器在当前代码路径上遇到它不支持的操作时,便会退回到解释器模式。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《OpenResty从入门到实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(18)

  • 北漂鱼
    对于一个OpenResty入门者一开始讲这些性能和低层的知识有些枯燥了,毕竟还没写过几个OpenResty的实例,对性能的差异没什么感觉,基础知识还没掌握全更难深入底层。有如学习java的初学者一开始就看《Java编程思想》。可否尝试在后面的实际例子中引出这些知识点。

    作者回复: 后面会专门介绍 OpenResty 的 Lua API。LuaJIT 的这些内容有个印象即可。

    2019-06-17
    10
  • 回家
    封装字符串查找函数:
    local function new_string_find(src, dst, regex, pos)
    if regex then
    local ctx = {pos = pos or 1}
    return ngx.re.find(src, dst, "jo", ctx)
    else
    local pos = pos or 1
    return string.find(src, dst, pos, true)
    end
    end
    2019-06-17
    4
  • helloworld
    老师,下面这个设置lua库的搜索路径的代码,最后为什么要拼接package.path本身啊?
    package.path = "../myLuaTest/myLuaCode/?.lua;"..package.path

    作者回复: package.path 是默认的查找路径,你可以单独把它 print 出来看下里面的值。不拼接的话,就把默认查找路径全都覆盖掉了。

    2019-06-17
    3
  • Geek_89bbab
    希望老师分享一下写 openresty代码时用什么编辑器比较好,代码补全,定义跳转,引用跳转等如何配置。老师你们写openresty的时候是怎么来做的?直接vim操作,还是有更智能些的IDE?

    作者回复: 现在还没啥好用的编辑器,我用的是 vs code

    2019-06-17
    3
  • Guyun
    好~
    2019-07-04
    1
  • 燕羽阳
    1. lua的语法比较简单,如果有编程基础的话,一天就可以入门了。推荐大家两本书《lua程序设计》lua入门必备,《lua设计与实现》深入解释器虚拟机的原理。
    2. 之前写过一点openresty和kong,但是从没注意过性能问题。今天的NYI,老师讲的非常棒,完整的实战方案,超赞👍
    3.我对jit完全不熟悉,请问老师,jit是按照函数为单位来编译么?函数中有一个NYI,整个函数就是解释运行么?

    作者回复: 是按照原语来编译的,也就是 `ipairs` 、`string.find` 这种的颗粒度,并不是你自己写的 function

    2019-06-17
    1
  • Forturn
    楼上说的有道理,目前还没掌握基本的语法,还不会写一些基本的功能,就去学底层的东西,有点摸不着头脑,也不懂这些。不知道后面会不会具体事例

    作者回复: 看不懂没有关系,重要的是记得有LuaJIT 和 NYI 这个东西,后面遇到问题方便查找。

    2019-06-17
    1
  • Geek_e59303
    什么是代码热路径啊
    2019-11-12
  • sheng
    这里的一个数量级是指十倍的意思么?

    作者回复: 是的

    2019-08-09
  • sheng
    你好,性能差距至少一个数量级是指多少?可否举个例子?
    2019-08-09
  • KoALa
    教程中反复提到了“LuaJIT 的作者目前处于半退休状态”,感觉这个情况很不乐观啊...

    作者回复: Kong 和 OpenResty 的团队中,都有人在逐步接手。开源项目只要有人在使用,就不会死掉,不用担心。

    2019-07-25
  • 莫然
    pairs的例子稍作修改,如下:
    local t = {}
    for i=1,100 do
         t[i] = i
    end
     
    for j=1,10 do
        for k,v in pairs(t) do
             --
        end
    end
    jit.log里输出的是:[TRACE 1 t.lua:123 loop]

    如果改成如下代码:
    for j=1,100 do
        for k,v in pairs(t) do
             --
        end
    end
    jit.log里输出的是:
    [TRACE 1 t.lua:123 loop]
    [TRACE --- t.lua:128 -- NYI: bytecode 72 at t.lua:129]
    [TRACE --- t.lua:128 -- NYI: bytecode 72 at t.lua:129]

    为什么循环10的时候没有NYI的提示?

    作者回复: LuaJIT 的优化是随机触发的,要足够热才可能尝试去优化

    2019-07-11
  • psoracle
    既然是优先使用openresty api,再luajit的api,老师请问一下,luajit的API在哪里能找到,看过 http://luajit.org/ext_jit.html 与 http://wiki.luajit.org/JIT-Compiler-API?

    作者回复: 还有 https://github.com/LuaJIT/LuaJIT/blob/v2.1/doc/extensions.html

    2019-07-04
  • 风翱
    能否说明一下学习的路径或介绍一些书籍,可以在课程之外进行补充学习? 现在学习的过程中,对于文中讲解的内容,真的只有一个印象,然后就有点不知道如何下手了。

    作者回复: 推荐看 OpenResty 相关的开源项目,比如 lua-resty 库。

    2019-06-20
  • NEVER SETTLE
    经常会发现openresty运行一段时间,性能会差很多。然后reload一下性能会好很多。这个问题一直困扰很久了,不知道如何进行排查。 以前两天的情况,高峰期CPU使用率超过了60%,然后reload一下,CPU使用率就降为30%。

    作者回复: 需要用火焰图分析下 on-cpu 才行

    2019-06-19
  • John
    老师,我在用op实现一个自定义逻辑的风控系统,想请教一下动态配置生效的问题,如何在不reload的情况下使配置生效,我想了两个办法:1,使用全局变量存储配置文件,提供一个api更新全局变量;2,使用ngx.shared.DICT,将配置文件存储在共享内存中。请问是否合理,或者是否有其它思路

    作者回复: 你可以使用一个 timer,定时的查询是否有新的配置,并把新配置写到类似 shared dict 的缓存中。

    2019-06-18
    1
  • 涉蓝
    对于初学者是不是 要先学 lua -> luajit -> openresty api -> 其他第三方包
    按这种先把 文档啥的都扒一遍才行呢?
    我对于使用有点疑惑,openresty可以做 网站普通后端语言可以做的事 譬如连数据库做前端页面 但这显然并不是它主要适合的部分吧 毕竟其他后端语言一大把,文档生态库好的多的是
    所以是API 网关的 开发 或者 nginx 无法配置热修改的 补充吗?

    作者回复: 这个问题其实要回到 OpenResty 诞生的那个时候来看, 2007 年,支持同步非阻塞的语言凤毛麟角。
    即使是现在,后端语言可以达到 OpenResty 这种性能级别的也不多。
    API 网关和软 WAF 算是开发者的自然选择,OpenResty 其实能做的不止这些。

    2019-06-17
  • John
    请教一下老师,当op中的lua规则和nginx配置文件产生冲突,比如nginx配置了rewrite规则,又同时引用了rewrite_by_lua_file,那么这两条规则的优先级是什么?

    作者回复: 这个具体要看 nginx 配置的 rewrite 规则是怎么写的了,是 break 还是 last。这个在官方文档中有注明,并且配了一个示例代码:
     location /foo {
         rewrite ^ /bar;
         rewrite_by_lua 'ngx.exit(503)';
     }
     location /bar {
         ...
     }
    上面这个配置中,ngx.exit(503) 是不会被执行的。但是,如果改成:
    rewrite ^ /bar break;

    ngx.exit(503) 就是可以执行的。

    2019-06-17
    1
收起评论
18
返回
顶部