Hello!
2014-04-08 23:07 GMT-07:00 John Zhao:
> 在nginx.conf文件中 加入下列测试location,single_test
> 中调用ngx.location.capture_multi产生多个子请求,子请求中只是say('hello');示例如下:
> location = /multi_test {
[...]
> }
> location = /single_test {
[...]
> }
> location = /test {
> content_by_lua '
> ngx.say('hello world!')
> ';
> }
你的这个例子里有两处语法错误。我在尝试你例子的时候已经自己修正了。建议下回直接复制粘贴你经过测试的代码片段或配置片段,以节约我的时间,同时也可以让我确认你自己运行过你贴的示例。
> 用 ab -n 100000 -c 100 "http://127.0.0.1:8080/single_test"
> 测试RPS能达到1.7W;而用同样命令测试ab -n 100000 -c 100 "http://127.0.0.1:8080/multi_test"
> RPS只能达到7900,ngx.location.capture_multi性能损失很大可以这样理解吗?
>
你的用例和观察到的现象并不能得出你的结论。
这是因为你的 /multi_test 发起并执行了 11 个子请求,而你的 /single_test
只发起并执行了一个子请求。换句话说,前者相对于后者完成了 11 倍的工作量,你觉得这种比较本身公平吗?
我在用 ab 对 /multi_test 保持压力时针对 nginx worker 进程作了一张 on-CPU 火焰图(见
https://github.com/agentzh/nginx-systemtap-toolkit#sample-bt ):
http://agentzh.org/misc/flamegraph/ngx-lua-multi-capture.svg
从图上可以看到,近一半的 CPU 时间用在写 http 输出上面;而对于余下的一半,一部分是 ngx.location.capture*
把父请求的请求体复现给子请求,一部分则是你的 location = /test 本身的开销(主要是 content_by_lua
本身每请求初始化的开销)。
值得一提的是,ngx.location.capture() 的底层实现也是调用的
ngx.location.capture_multi(),所以你只是在比较 11 个子请求和 1 个子请求之间的性能差别。
一般地,使用 ngx_lua 的 ngx.thread API 结合 cosocket API 会获得优于
ngx.location.capture* API 的性能。所以应当尽量使用前者。NGINX 子请求的开销还是相对比较大的。
Regards,
-agentzh