用 vue.js 的框架 ant-design vue pro 实现的一个监控系统,后端用第三方开源组件 zabbix 提供监控数据采集,前端的展现中一个页面会同时请求 N 个图表,页面响应时间很慢,极端状况下甚至达到 10s , 用户体验不好,因此领导给了个小任务,优化整个页面的请求响应。html
领导发现页面响应很慢,说了一句:“这些图表显示这么慢,应该一开始就想着优化的”,这里我以为这个观点有待商榷,最近在读《重构》这本书,里面的一个观点我很认同:“作任何事情,先作出来,再优化”,这是一个应用面很广的策略,跟 Linux 的哲学之一“单个程序负责一个小功能”的组织模式,都有普遍用法;当工期有限的状况下,先把东西作出来(这里不光指代程序,而是任何产品或者其余交付物),再考虑优化它,由于有了产出物才会有后续的东西,并且任何人不可能一开始就把全部的状况和变化的需求考虑得面面俱到。Linux 哲学里的那句话一样能够用于人员组织、社会分工合做方面,专人专事,让专业人士来作(好比:黑人抬棺),效率不言而喻。前端
显示很慢的图以下:vue
以前历来没有作过性能优化和分析,此次从零开始优化,须要本身认真分析排查,这个页面会请求同一个接口,不获取不一样监控指标的图表数据,大概 10-20 个图表渲染,在排查以前想到可能的性能瓶颈:java
做为全栈开发者,首先想到的是从后端服务开始优化,而没有优化经验怎么入手,固然是先找轮子了,Google 找了一下工具,有以下可用:mysql
询问了下同事,发现你们也没什么优化经验,因此我选用了以前了解了一点的 Arthas 工具做为诊断。jquery
进入 Arthas 的官网,能够用它的在线教程快速入门(它是一个沙盒的 linux 环境,可以快速掌握 Arthas 的基础使用和概念),而后,知道使用方法后,把 Arthas 的 jar 包放到个人 centos 线上测试环境中(Arthas 自己也支持 windows 的,能够本地调试)linux
java -jar arthas-boot.jar
而后用 trace 命令来追踪某个方法调用链路上的耗时ios
trace xxxx.xxx xxx
此时,咱们请求前端代码,就能在后台看到对这个调用方法的每一步的耗时了git
此时,咱们就能够去具体的代码分析耗时缘由了,重复 trace 能够进一步精肯定位哪一个方法开销最大。程序员
Arthas 还有不少很是强大的功能,对于 java 程序员很是友好,建议自行探索:
发现接口响应时间为 500 ms 后,感受性能瓶颈可能不在后端(固然,这里确定还有必定的优化空间,可是不是主要矛盾)
发现后端接口响应时长没有那么夸张以后,把目光放到了前端上来,F12 打开了 chrome 浏览器的开发者工具后,发现几个问题:
继续 Google ,搜索 同时发送多个请求形成 chrome stalled 时长过大(固然用英文关键词搜索),果真在 stackoverflow 发现了这个问题的解答,[https://stackoverflow.com/questions/27513994/chrome-stalls-when-making-multiple-requests-to-same-resource],里面提到了几种解决方式:
Cache-Control: no-cache, no-store
,这个我在后端增长后没有效果,这里别人讨论的是浏览器的缓存机制形成请求过慢?ran='+Math.random()
,让请求不一致,达到欺骗浏览器,让它每次都发送一个新的请求,这个实验后也不能让响应时间变短此时的我陷入了沉思,问题究竟处在哪里?同事提醒我一个规律,超过 6 个请求后,后面的都会开始有一串灰色的长耗时(就是咱们看到的 stalled),另一个同事说好像是 jquery 的限制仍是怎样,继续搜索,发现这个是 浏览器对同一个域名的多并发请求个数的限制,参考博文:
发现了这个限制以后,咱们把图表的请求个数限制在6个之内,跟以前相比页面渲染速度确实有明显提高,规避了请求数量过多形成 stalled 的问题,固然,这个只是一种解决方案,v2ex 上的同窗有不少其余可参考的解决方式。
参考腾讯的蓝鲸监控里的图表绘制,它们采起了分页请求控制数量,尽可能给客户展现少的图表,同时提供每页显示更多的选择(每页 4 个图表秒开,8个的时候就开始有 loading 的效果了)
解决了前端超过 6 个请求的阻塞问题,问题到了有的请求 Waiting(TTFB)很长上来了,这又是个什么呢?搜索一番发现,这个是服务端的响应(看来后端仍是颇有优化空间的,参考博文:ttfb是什么)
这个图表请求接口有的会特别慢,甚至有的会 2-3 秒,定位到问题出在跟三方组件 zabbix-server 的请求交互上,这是很是须要优化的,打开咱们的 fiddle 抓包工具看请求:
fiddle 使用小技巧
控制面板-Internet 选项-链接-局域网设置-代理服务器(不勾选为 LAN 使用代理服务器)
设置地代码的代理端口为 8888 (fiddle 默认使用的就是 8888)
这样设置后,fiddle 就只会抓取我本地 idea 发送的请求了,过滤掉了浏览器里的干扰请求。
用 Fiddler 抓 Postman的模拟请求
每一个图表请求分三个:
参考 zabbix 的官方文档,作了代码层面的优化:
后端优化还包括:用特定的监控项取代发现类型监控项(这个是发现磁盘接口过慢的缘由,会发现 70 多个文件目录),请求某个主机的全部发现类型监控项写到咱们的业务库(只请求一次)等;
单个后端请求的瓶颈在于咱们用 zabbix api 去请求 zabbix server 所返回的过程,因此,对zabbix server 自己的优化也是整个链路的重要方面。参考 zabbix 的官方文档后,有这样一些方面:
历史数据保存时间尽量的小,这样数据库不会超负荷运行,查询的效率也更高
[https://www.zabbix.com/documentation/4.0/zh/manual/config/items/history_and_trends]
调优zabbix的数据库引擎,这个是调优最重要的部分(因为没有 dba ,本人对数据库调优也不懂,这个暂时没法作到,搜索了下咱们使用的 mysql 5.6 使用的是 InnoDB 引擎)
[https://www.zabbix.com/documentation/4.0/zh/manual/appendix/performance_tuning]
对于 zabbix 自己优化官方文档还没整个看一遍,等所有找一遍说不定能找到进一步压榨性能的方法~
这次优化涉及了不少方面,前端、后端、服务器等,优化后的用户体验获得了提高,也遇到了一些坑,不断提升本身解决问题的能力,才是程序员的价值,共勉!