当前位置: 首页 > 科技观察

如何使用火焰图分析服务器负载

时间:2023-03-21 17:08:16 科技观察

LucidChart提供在线编辑流程图、网络拓扑图、ER图、UML图、脑图等,拥有超过700万用户,因为其简单直观的交互方式它独特的体验和强大的多人协作功能,是替代Visio的最佳选择。在Lucid,我们使用面向服务的架构来构建我们的系统。其中,字体服务就是其中之一。负责根据字体家族名称和unicode编码范围提供相应的字体服务,同时对用户上传的字体进行校验和校验。在生产中,该服务的负载比我们预期的要高(使用或等待CPU的平均线程数)。特别是从去年开始,我们注意到字体服务负载高得惊人,尤其是在晚上这样的低流量时段。幸运的是,我们最终找到了根本原因并进行了改进,极大地提高了服务的整体性能和稳定性。您将在下面了解我们是如何做到的。图一:字体服务变更前后平均服务器负载对比通过火焰图调试发现问题我们从Netflix找了一个很棒的火焰图工具,部署到生产环境中。该工具可以结合来自多个不同调试分析工具的数据并生成火焰图来可视化服务器和JVM资源使用情况。如下图所示,每个矩形代表一个栈帧,而矩形的宽度代表资源的使用情况(比如CPU时间),Y轴代表调用栈。通过识别那些宽矩形块,您可以快速缩小问题范围。在对字体服务进行调试和故障排除时,它为我们提供了极大帮助。图2:服务器在高负载下服务的火焰图。我们收集了数据并为高负载下的字体服务生成了几个火焰图。下图是其中之一,具体显示了JVM相关堆栈的部分。可以分析出大部分时间花在了libz.so这一步(gzip使用这个库进行压缩/解压操作),剩下的大部分时间花在了XML转义和UTF-8编码上。图3:JVM相关堆栈活动的部分火焰图找到慢的原因首先,我多说一下这个字体服务的背景。我们将所有与字体相关的数据存储在AmazonS3中,特别是将每种字体的每个unicode范围作为一个单独的S3对象。当其他服务请求字体系列、一组unicode范围或用户定义的字体时,它们会向字体服务请求字体数据,然后字体服务将返回封装在XML中的字体数据。该功能非常简单,没有明显的计算密集型。但是对于出现的高负载问题,火焰图帮助我们确定了问题-libz、XML转义和UTF-8编码都在使用大量CPU。但是为什么会有那么多的编码和压缩消耗呢?你还记得夜间的负载是最高的吗?我们的晚上(美国山区时间)刚好是亚洲的白天,这一带的用户很多都是用中文和日文。或者像韩语这样的亚洲语言。会进行大量的gzip解压→UTF-8解码→XML转义→UTF-8编码→gzip压缩。与拉丁语系相比,单个CJK的unicode范围比拉丁语系大2个数量级(1MB:60KB)。所以上面的转换过程都放在了CPU上,特别是压缩和解压,以及XML转义等操作。如何改进?字体服务对请求的响应本质上只是S3上原始数据的集合。它确实需要执行一些重要的附加任务,例如权限检查和从字体系列中检索名称。但是,字体服务不需要站在S3前面来代理那些字体数据!所以解决方法很简单,只要返回一个包含S3对象(即字体数据)链接的列表作为响应,字体服务不再从S3下载和重新编码字体数据。所以从图1可以看出,负载几乎降低到可以忽略不计的程度。总结通过对生产环境的调试分析,我们可以发现并剔除那些不必要的任务和作业,从而降低服务器的负载。使用火焰图等分析工具来帮助识别CPU密集型操作。压缩/解压缩和各种编码/解码操作是昂贵的。如果客户端可以直接访问数据,那么与代理(客户端请求)数据相比,直接返回链接是最好的选择,可以显着提高整体性能。