[17:47 root@aufs:~/workspace/wrk/wrk-4.0.1] # ./wrk -t12 -c100 -d30s http://9.91.39.77/scm/test
Running 30s test @ http://9.91.39.77/scm/test
12 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 18.91ms 2.24ms 67.62ms 95.12%
Req/Sec 424.97 40.53 484.00 66.94%
152409 requests in 30.03s, 75.73MB read
Requests/sec: 5075.17
Transfer/sec: 2.52MB
[18:18 root@aufs:~/workspace/wrk/wrk-4.0.1] # ./wrk -t12 -c100 -d30s http://9.91.39.77:9010/scm/test
Running 30s test @ http://9.91.39.77:9010/scm/test
12 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.88ms 1.13ms 22.50ms 76.44%
Req/Sec 1.65k 208.15 2.39k 68.78%
590453 requests in 30.02s, 257.60MB read
Requests/sec: 19670.87
Transfer/sec: 8.58MB
Hi,基于openresty开发了一个应用路由模块,大致工作流程如下:1. 根据请求,通过REDIS查询路由信息,首次会将json解码后的结果保存在lrucache中2. 负载均衡出一台后端服务器3. 通过ngx.var AIP将一些信息传递,通过ngx.exec API内部跳转到@router_proxy location
4. @router_proxy location中通过access_by_lua对后端服务器进行域名解析。通过proxy_pass转发到upstream5. upstream 中通过balancer_by_lua.set_current_peer设置6. @router_proxy location中通过header_filter_by_lua进行时延统计
从对比测试结果,可以看到相比原生的Nginx转发差距非常大,想请教这是否合理呢?
有啥具体的调优的思路呢?或者我应该最先从哪个方向进行分析?使用lj-lua-stacks.sxx看了下lua面的cpu:
额,原谅我暂时传不了图片。
--Thanks.
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html
location = /router_proxy {internal;proxy_set_header Host $router_forward_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $http_x_forwarded_for;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Connection "";proxy_set_header X-Forwarded-Host $router_forward_http_host;proxy_http_version 1.1;proxy_pass http://${router_backend}${router_forward_uri};}
local math_floor = math.floorlocal ngx_var = ngx.varlocal router_ctx = {}-- we run the rewrite and access phase here-- it's more lower cpu usage than using rewrite_by_lua_* and access_by_lua_*--require('router_rewrite_phase').rewrite_phase(router_ctx)require('router_access_phase').access_phase(router_ctx)local router_config = require('router_config')local precision = function(double_num)return math_floor(double_num*10000)/10000end-- use nginx proxy_pass to bypass requestlocal function get_proxy_endpoint(app_type,request_mode)local route_type = app_type or "was" -- default route type is wasif request_mode == "upgrade" then -- upgrade is the special case,ignore route_typereturn "/router_upgrade"endif route_type == "was" thenreturn "/router_was"end-- others use the normal proxy outputreturn "/router_proxy"endlocal router_request_mode = "proxy_pass"local t_router_upstream_config = router_config.upstreamlocal ngx_upstream = require('lib.router_ngx_upstream')(t_router_upstream_config)local t_used_upstream = {name = "testpro",list = {"test_pro_9.91.39.111_9075","test_pro_9.91.39.111_9076"},type = "pro"}local t_upstream_server_infos = {["test_pro_9.91.39.111_9075"] = {servers = {hostname = "9.91.39.111",port = 9075}},["test_pro_9.91.39.111_9076"] = {servers = {hostname = "9.91.39.111",port = 9076}},}local used_upstream_name,used_upstream_idx,err = ngx_upstream:choose(t_used_upstream,nil)local real_forward_host = ngx_var.hostlocal real_forward_http_host = ngx_var.http_hostlocal real_forward_uri = ngx_var.request_uriif router_config.upstream.balancer.enable then-- set ngx.var for balancer_by_lualocal router_backend = router_config.upstream.balancer.upstreamlocal balancer_host = t_upstream_server_infos[used_upstream_name]["servers"]["hostname"]local balancer_prepare = require "router_balancer_prepare"ngx_var.router_balancer_host = balancer_prepare.prepare(router_backend,balancer_host)ngx_var.router_balancer_port = tonumber(t_upstream_server_infos[used_upstream_name]["servers"]["port"])ngx_var.router_backend = router_backendelsengx_var.router_backend = used_upstream_nameendngx_var.router_sticky_key = nilngx_var.router_plant_key = nilngx_var.router_plant_val = nilngx_var.router_status_header = nil-- save forward host and pathngx_var.router_forward_host = real_forward_hostngx_var.router_forward_http_host = real_forward_http_hostngx_var.router_forward_uri = real_forward_uri-- save router_sticky_config into nginx variables temporarilyif not router_sticky_config then router_sticky_config = {} endngx_var.router_sticky_type = router_sticky_config.typengx_var.router_sticky_create = router_sticky_config.createngx_var.router_sticky_lookup = router_sticky_config.lookupngx_var.router_sticky_expires = router_sticky_config.expireslocal ups_start_time = ngx.now()local ngx_elapsed_time = ups_start_time - ngx.req.start_time()-- process time from accept to proxyngx_var.router_request_time = precision(ngx_elapsed_time)ngx_var.router_ups_start_time = tostring(ups_start_time)local proxy_point = get_proxy_endpoint("tomcat",router_request_mode)return ngx.exec(proxy_point)
nginx version: openresty/1.9.7.4built by gcc 4.1.2 20080704 (Red Hat 4.1.2-55)built with OpenSSL 1.0.2g 1 Mar 2016TLS SNI support enabledconfigure arguments: --prefix=/opt/router/openresty/nginx --with-cc-opt=-O2 --add-module=../ngx_devel_kit-0.2.19 --add-module=../echo-nginx-module-0.58 --add-module=../xss-nginx-module-0.05 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.30 --add-module=../form-input-nginx-module-0.11 --add-module=../encrypted-session-nginx-module-0.04 --add-module=../srcache-nginx-module-0.30 --add-module=../ngx_lua-0.10.2 --add-module=../ngx_lua_upstream-0.05 --add-module=../headers-more-nginx-module-0.29 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.16 --add-module=../redis2-nginx-module-0.12 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.14 --add-module=../rds-csv-nginx-module-0.07 --with-ld-opt=-Wl,-rpath,/opt/router/openresty/luajit/lib --with-pcre=/mnt/compile/nginx/openresty-1.9.7.4/../pcre-8.36 --with-zlib=/mnt/compile/nginx/openresty-1.9.7.4/../zlib-1.2.8 --with-openssl=/mnt/compile/nginx/openresty-1.9.7.4/../openssl-1.0.2g --with-pcre-jit --add-module=/mnt/compile/nginx/openresty-1.9.7.4/../ngx_http_dyups_module-0.2.9+ --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-openssl-opt=enable-tlsext
./wrk -t12 -c100 -d30s http://9.91.39.77/scm/test`Running 30s test @ http://9.91.39.77/scm/test12 threads and 100 connectionsThread Stats Avg Stdev Max +/- Stdev
Latency 14.48ms 3.29ms 100.49ms 89.32%Req/Sec 557.23 72.63 1.04k 66.20%201007 requests in 30.07s, 99.85MB readRequests/sec: 6683.57Transfer/sec: 3.32MB
./wrk -t12 -c100 -d30s http://9.91.39.77:9010/scm/test`Running 30s test @ http://9.91.39.77:9010/scm/test12 threads and 100 connectionsThread Stats Avg Stdev Max +/- Stdev
Latency 5.79ms 1.94ms 51.76ms 85.56%Req/Sec 1.40k 220.43 1.94k 69.14%502658 requests in 30.02s, 219.30MB readRequests/sec: 16741.50Transfer/sec: 7.30MB
--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html
<lua-land-cpu-flame-graph-1-worker.svg><c-land-cpu-flame-graph-1-worker.svg>
在 2016年4月15日,上午8:38,Guanglin Lv <anym...@qq.com> 写道:多谢doujiang的分析,不过我还是挺困惑的;1、主流程就在access和header阶段,log阶段被我注释掉了;
2、严格来说每次请求会操作两次shdict,应该不算是频繁吧
3、我的lrucache应该是100%命中,我测试之前是先缓存好的,过期时间是1分钟。所以30s的压测时间内是都要命中的;4、请求的access处理过程中,会生成一些临时表,最大的就是处理上下文信息,这个表会通过ngx.ctx传递到header、balancer阶段使用;
5、全局表操作应该没有的才对,除了access/header/balancer都是模块的调用,ngx_http_lua_create_new_globals_table这个是在哪看到的呀。
在 2016年4月15日,上午8:38,Guanglin Lv <anym...@qq.com> 写道:
多谢doujiang的分析,不过我还是挺困惑的;1、主流程就在access和header阶段,log阶段被我注释掉了;
2、严格来说每次请求会操作两次shdict,应该不算是频繁吧
3、我的lrucache应该是100%命中,我测试之前是先缓存好的,过期时间是1分钟。所以30s的压测时间内是都要命中的;4、请求的access处理过程中,会生成一些临时表,最大的就是处理上下文信息,这个表会通过ngx.ctx传递到header、balancer阶段使用;
5、全局表操作应该没有的才对,除了access/header/balancer都是模块的调用,ngx_http_lua_create_new_globals_table这个是在哪看到的呀。
Hello在 2016年4月15日,上午8:38,Guanglin Lv <anym...@qq.com> 写道:多谢doujiang的分析,不过我还是挺困惑的;1、主流程就在access和header阶段,log阶段被我注释掉了;所以我说 log 阶段是通用的优化,与 ngx_lua 无关抱歉,我上篇回帖有错别字,开始 -> 开启,开启 buffer 应该会更快,如果你的业务接受的话(我猜你现在应该没开,或者设置的略小)
2、严格来说每次请求会操作两次shdict,应该不算是频繁吧我之前理解的是,应该应该不需要每请求操作,如果你需要,两次不算多火焰图其实是帮助我们了解实际运行情况,如果实际跟我们理想的有区别,那就需要优化了如果你的业务需要两次,那么也合理
3、我的lrucache应该是100%命中,我测试之前是先缓存好的,过期时间是1分钟。所以30s的压测时间内是都要命中的;4、请求的access处理过程中,会生成一些临时表,最大的就是处理上下文信息,这个表会通过ngx.ctx传递到header、balancer阶段使用;好吧,这样看来你的业务逻辑也还有点复杂那么你可以对照 Lua land 的火焰图,看看是不是有出乎你想象的
5、全局表操作应该没有的才对,除了access/header/balancer都是模块的调用,ngx_http_lua_create_new_globals_table这个是在哪看到的呀。确实占比很少,不好找,不过你可以在 vi 里打开 svg,搜索
Hello!
2016-04-13 18:11 GMT-07:00 Guanglin Lv:
> 1. 统一一个location入口,直接proxy_pass走,避免调用ngx.exec
> 2. 优化ngx.var API的调用,上下文信息传递使用ngx.ctx
ngx.ctx 也应尽量减少使用,因为 ngx.ctx 也涉及元表操作。
>
> C/Lua层面的火焰图如附件所示。
>
从你的 C 级别火焰图上看,有如下的优化方法:
1. 尽量多地让你的热 Lua 代码路径被 JIT 编译。具体做法是:尽量使用 lua-resty-core 库,避免在热代码路径上使用
LuaJIT 的 NYI 原语 [1]. 从火焰图上看,你的绝大部分 Lua 代码都是被 LuaJIT 解释执行的,并没有被 JIT
编译(显示为那些 lj_BC_xxx 的函数帧)。
3. 启用 luajit 的 dual number 模式,以避免昂贵的浮点数到字符串的转换(火焰图中对应 lj_strfmt_num
帧)。具体做法是使用下面的命令重新编译 OpenResty:
./configure --with-luajit-xcflags="-DLUAJIT_NUMMODE=2"
值得一提的是,最新的 LuaJIT 2.1 包含了一个优化过的浮点数字符串化的实现,而并没有再使用性能较差的 glibc
里面的实现。不过最新的 OpenResty 还没有包含这么新的 LuaJIT.