了解 OpenResty XRay 是如何做到帮助企业定位应用程序存在的问题以及优化其效率的。

了解更多 LIVE DEMO

本教程演示了在 OpenResty 中对用户 Lua 代码进行基准测试的正确方法和错误方法。

cd ~
mkdir time-lua
cd time-lua/

首先,要保证我们的 CPU 始终处于全速运转状态。

echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

截图 2

它通常默认取值 powersave 而我们需要设置成 performance

对一些 Lua 代码进行计时的最简单方法是使用 time 命令和 resty 命令。

time resty -e 'ngx.re.find("hello, world.", [[\w+\.]], "jo")'

截图 4

但这种方法有一个问题。resty命令本身有一个启动和退出的开销。

time resty -e ''

截图 6

我们可以看到在这台机器上的开销大约有 11 毫秒。

相反,我们应该使用 OpenResty 提供的ngx.now Lua API函数。

restydoc -s ngx.now

截图 8

让我们把我们的 Lua 代码放到一个名为 ./bench.lua 的文件中,以便更好地阅读。

我们进行以下编辑:

  1. 首先,我们要确保 nginx 里面的缓存时间是最新的。
  2. 然后我们记录的开始时间有毫秒的精度。
  3. 然后把我们前面提到的正则匹配调用。
  4. 然后我们再更新缓存时间。
  5. 最后,通过做时间减法输出经过的时间。
  6. 让我们保存文件。
ngx.update_time()
local begin = ngx.now()
ngx.re.find("hello, world.", [[\w+\.]], "jo")
ngx.update_time()
ngx.say("elapsed seconds: ", ngx.now() - begin)

截图 15

然后运行 resty 这个 shell 命令。

resty bench.lua

截图 18

它记录的延迟时间大约是 1 毫秒。但我们很快就会发现它很不准确。

正确的方法是在 bench.lua 文件中做如下编辑:

  1. 把调用放到一个名为 target 的 Lua 函数中。
  2. 然后先调用这个函数 100 次作为热身。现在这个 target 函数应该在这个循环执行完后进行 JIT 编译。
  3. 然后在定时码区域里面,我们反复调用 1000 万次。
  4. 最后我们计算平均时间。
local function target()
    ngx.re.find("hello, world.", [[\w+\.]], "jo")
end

for i = 1, 100 do
    target()
end

ngx.update_time()
local begin = ngx.now()

local N = 1e7
for i = 1, N do
    target()
end

ngx.update_time()
ngx.say("elapsed: ", (ngx.now() - begin) / N)

截图 25

我们现在再次运行这个脚本。

resty bench.lua

截图 26

我们可以看到,每次调用仅仅是 30 纳秒左右。比之前的结果快了很多很多倍!

实际上,我们可以进一步确保在我们给代码计时之前,没有死掉的 GC 对象还没有被回收,只要在第一个 ngx.update_time() 调用之前插入以下一行代码。只需在第一个 ngx.update_time() 调用之前插入以下一行代码。

collectgarbage()

截图 29

在这里,我们强制执行一个完整的 GC 周期,然后再记录开始时间。

但是,它对我们这里的例子没有什么帮助。这是因为我们的定时代码无论如何也不会创建很多 GC 对象。

我们可以通过避免不必要的 Lua 表查找操作,使 target 函数更快。

local re_find = ngx.re.find

local function target()
    re_find("hello, world.", [[\w+\.]], "jo")
end

截图 33

但这里的差别可能比较小。

截图 35

这就是我今天要讲的内容。希望你觉得有趣。 如果你喜欢这个教程,请订阅这个博客网站和我们的 YouTube 频道B 站频道。谢谢!

关于本文和关联视频

本文和相关联的视频都是完全由我们的 OpenResty Showman 产品从一个简单的剧本文件自动生成的。

关于作者

章亦春是开源 OpenResty® 项目创始人兼 OpenResty Inc. 公司 CEO 和创始人。

章亦春(Github ID: agentzh),生于中国江苏,现定居美国湾区。他是中国早期开源技术和文化的倡导者和领军人物,曾供职于多家国际知名的高科技企业,如 Cloudflare、雅虎、阿里巴巴, 是 “边缘计算“、”动态追踪 “和 “机器编程 “的先驱,拥有超过 22 年的编程及 16 年的开源经验。作为拥有超过 4000 万全球域名用户的开源项目的领导者。他基于其 OpenResty® 开源项目打造的高科技企业 OpenResty Inc. 位于美国硅谷中心。其主打的两个产品 OpenResty XRay(利用动态追踪技术的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最适合微服务和分布式流量的全能型网关软件),广受全球众多上市及大型企业青睐。在 OpenResty 以外,章亦春为多个开源项目贡献了累计超过百万行代码,其中包括,Linux 内核、Nginx、LuaJITGDBSystemTapLLVM、Perl 等,并编写过 60 多个开源软件库。

关注我们

如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:

我们的微信公众号

翻译

我们提供了英文版原文和中译版(本文) 。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!