文字内容
1. OpenResty 项⽬目性能优化实践 Alex Zhang Github: https://github.com/tokers 2017/12/23 OpenResty Meetup 杭州
2. • 常⽤用性能分析⼯工具 • 基于 OpenResty 的项⽬目的特点 • 基于 OpenResty 的项⽬目细节优化
3. 常⽤用性能分析⼯工具 资源分析 负载分析 • top • perf • pidstat • SystemTap • iostat • FlameGraph •… •…
4. Perf • http://www.brendangregg.com/perf.html • 多种不不同种类事件,perf list • 进程级别的事件统计, perf stat -p • 函数级别的事件统计,perf report -p && perf record
5. # perf stat -e 'context-switches,page-faults,branch-misses' -p 2623564 ^C Performance counter stats for process id '2623564': 3 0 1,346 context-switches page-faults branch-misses 3.223158849 seconds time elapsed # perf record -F 100 -p 2623564 -g -- sleep 5 [ perf record:'>record: Woken up 1 times to write data ] [ perf record:'>record: Captured and wrote 0.009 MB perf.data (5 samples) ] # perf report
7. SystemTap • 动态追踪 -⾃自定义探针 • DSL - 简单灵活的脚本语⾔言 • ⽤用户态空间追踪和内核态空间追踪 • 调⽤用栈回溯 • ⾮非侵⼊入式
9. FlameGraph
11. Off-CPU - http://www.brendangregg.com/offcpuanalysis.html
12. 基于 OpenResty 的项⽬目有何特点?
13. • 多 worker 模式 • Nginx 事件循环 + 上层 Lua VM 接管 • 单线程,⼀一个时刻只有⼀一个请求在被处理理 • ⼀一个请求可能会经过多次调度之后才完成 • 分阶段的流⽔水线处理理(11 个阶段) • 各阶段的 Lua code 运⾏行行在不不同的 Lua 协程上
14. • 阻塞事件循环 • 锁抢占 • ngx.ctx VS ngx.var.VARIABLE • ⽇日志 • LuaJIT 的优势 • 编程习惯
15. 阻塞事件循环 引⽤用了了⼀一些 Lua/C 第三⽅方库
16. 怎么解决? 使⽤用 Cosocket
17. 锁抢占 • ngx.shared.DICT — e.g ngx.shared.DICT.get_keys() • nginx cache
18. Benchmark wrk -d 60s -t 4 -c 192 http://127.0.0.1:7106/t
20. ngx.ctx VS ngx.var.VARIABLE • ngx.ctx 是⼀一个“神奇”的 Lua table,⽽而⽤用法和普通 Lua table ⼀一致 • ngx.var.VARIABLE 利利⽤用了了 nginx 的变量量系统,同样可以⽤用于存储信息 • ngx.ctx 拥有⽐比 ngx.var.VARIABLE 更更好的效率
21. Why ngx.ctx is better • nginx 变量量只有字符串串⼀一种类型 • nginx 变量量需要分配内存⽤用于存放变量量值信息,且只能在请求结束时被释放 • Lua table 具有⾮非常⾼高的查找效率
22. Benchmark
24. ngx.ctx 的不不⾜足 • 相对昂贵的 metamethod 调⽤用 - 集中使⽤用时局部缓存 • ⽣生命周期局限在⼀一个 location - https://github.com/tokers/lua-resty-ctxdump
25. lua-resty-ctxump
26. ⽇日志 • 合理理设置 access_log 的 buffer ⼤大⼩小 - 避免过多的 write 系统调⽤用 • 关闭 access_log 和拦截 error_log,经过⽹网络传输到外部组件
27. 利利⽤用 LuaJIT 的优势 • 引⼊入 lua-resty-core(https://github.com/openresty/lua-resty-core) • 使⽤用可被 JIT 编译器器编译的函数(http://wiki.luajit.org/NYI) • 尽量量避免 table resize(table.new)
28. 良好的编程习惯 • https://blog.codingnow.com/cloud/LuaTips • 避免滥⽤用全局变量量 • 避免低效率的字符串串拼接 - table.concat
29. upyun-resty • https://github.com/upyun/upyun-resty • Tech Talks • Nginx Modules • Lua-Resty Libraries • Projects
30. Thanks