当前位置: 首页 > 后端技术 > Node.js

Node.js应用故障排查手册——大纲和一般问题指标介绍

时间:2023-04-03 14:52:10 Node.js

Wedge你是否想尝试开发Node.js应用,却总是听到有人说它不安全、稳定性差,想要推广和推广?在公司扩大大前端的能力范围和影响力,是无法说服技术领导的。JavaScript发展到今天,早已离开了当初浏览器的战场。借助于Node.js的诞生,其触角已经扩展到服务器端、PC端跨平台客户端解决方案等各个领域。对于开发者来说,它一如既往地处于黑盒状态——开发者无法感知它的运行状态,也没有很好的工具链在出现一些性能和内存问题时进行深度支持。本书基于Node.js性能平台,从你在开发和上线过程中可能遇到的诸多疑难杂症的角度,观察如何发现、定位和解决这些问题,帮助读者构建一个Node.js对语言更有信心。由于本书将属于Node.js开发的进阶内容,希望本书的读者具备以下基本技能:开发常规Node.js应用的能力;常见的数据库、缓存等操作负载均衡,多进程模型如Load、文件打开数等。如果使用容器,容器基础知识、资源管理等。本书首发于Github,仓库地址:https://github.com/aliyun-node/Node.js-Troubleshooting-Guide,云栖社区会同步更新。常规排查指标当我们第一次遇到线上异常时,很多人都会一头雾水。本节为预备篇,从服务器异常时常见的排查指标入手,帮助您建立更直观的问题处理体系。毕竟,如果我们在面对线上异常的时候连系统哪里出了问题都不知道,那么就更不可能借助Node.js性能平台来深入定位问题代码了。错误日志当我们的应用程序出现问题时,我们首先需要查看我们应用程序的错误日志,看看这段时间是否有错误抛出,导致我们的服务不稳定。这条信息显然因应用程序而异。当我们的项目比较大(Ecs/Docker节点较多)时,需要统一收集收集错误日志,以保证快速定位问题。一个比较简单的统一日志平台可以这样设计:一般使用消息队列(Kafka)作为采集服务器和代理之间的缓冲进行上报,以减轻双方的负载。ELK是一个比较成熟的日志服务。有了统一的日志平台,当我们的应用出现问题的时候,首先应该查看日志平台上当前的错误日志信息,尤其是那些频繁出现的错误日志,更应该提高警惕,需要仔细结合对产生错误的代码段进行回溯,确认是否是导致当前服务不稳定的罪魁祸首。Node.js性能平台还实现了简单的错误日志回溯+告警系统,本书第二部分会详细讲解。如果上述错误日内系统指标没有可疑信息(其实本节检查错误日志和系统指标的顺序并不固定,大家可以根据自己的需要),那么我们要注意以下问题是服务器负载导致的还是Node.js应用本身达到了极限?需要关注的一些常见系统指标如下:CPU&MemoryDisk磁盘使用率I/O负载TCP连接状态下面将对这些可能出现问题的系统指标一一进行说明。一、CPU&Memory使用top命令观察Node.js应用进程的CPU和Memory负载。一般来说,对于高CPU的Node.js进程,我们可以使用Node.js性能平台提供的CPUProfiling工具在线dump当前Javascript运行状态,然后寻找热点代码进行优化,具体在第二部分本书将进行更详细的解释。然后,对于内存负载高的情况,正常情况下会发生内存泄漏(或者意外的内存分配导致溢出),那么我们也可以使用性能平台提供的工具,将当前Javascript堆内存在线dump出来结合你的业务代码通过面向服务的分析来找到产生泄漏的逻辑。这里需要注意的是,目前的性能平台是可以对你的JS代码进行详细分析的。对于完全由C++扩展执行或者完全由V8/Libuv底层执行的逻辑(这部分功能后面会补充),以及没有在V8Heap上分配的内存,性能平台目前有没有更好的方法来分析和处理它。其实在我们遇到的案例中,大家写的JS代码占了绝大多数的问题。也就是说,性能平台比较完善的在线转储+对JS部分的服务分析,基本可以解决开发者95%甚至更多的问题。以上问题。二。磁盘使用情况df命令可以用来观察当前的磁盘使用情况。这也是一个很常见的问题。很多开发者会忽略服务器磁盘上的监控告警。当我们的log/coredump等大文件逐渐占用磁盘容量达到100%时,Node.js应用程序可能无法正常运行。Node.js性能平台还提供了磁盘监控,这将在本书的第二部分进行更详细的解释。三、I/O负载使用top/iostat和cat/proc/${pid}/io查看当前I/O负载。如果这一项的负载很高,也会导致Node.js应用卡顿等情况。四、TCP连接状态大多数Node.js应用程序实际上是Web应用程序,每个用户连接都会创建一个Socket连接。网络上会出现大量TIME_WAIT状态的连接,大量TIME_WAIT积压会导致Node.js应用卡顿(内核无法为新的请求分配创建新的TCP连接),我们可以使用netstat-ant|awk'/^tcp/{++S[$NF]}END{for(ainS)print(a,S[a])}'命令来确认这个问题。核心转储(Coredump)在线Node.js应用程序故障通常伴随着进程崩溃。借助一些守护进程的自检重启,我们的服务还在运行,但是我们不应该忽视这些突发事件。崩溃——当流量增加或者导致服务器问题的用户访问被别有用心的人抓到时,我们的集群就变得岌岌可危了。在大多数情况下,导致Node.js应用崩溃的错误日志往往不会记录在我们的错误日志文件中。幸运的是,服务器内核提供了一种机制,可以帮助我们在应用程序崩溃时自动生成核心转储(Coredump)文件,让开发者事后分析和还原犯罪现场。核心转储核心转储(Coredump)其实就是当我们的应用程序意外崩溃终止时,计算机自动记录下进程崩溃瞬间的内存分配信息、程序计数器、堆栈指针等关键信息,生成一个核心转储文件。因此,在获取到coredump文件后,我们可以使用MDB、GDB、LLDB等工具,对实际进程的crash原因进行分析诊断。生成文件触发coredump目前dump文件的生成方式主要有两种:一、设置内核参数,使用ulimit-cunlimited开启内核限制,考虑到在默认运行模式下,Node.js不会导致CrashJS触发coredump动作,所以我们可以在Node应用启动时加上参数--abort-on-uncaught-exception,让内核在发生未捕获异常时触发自动coredump动作。二。手动调用手动调用gcore的方法(可能需要sudo权限)手动生成,因为Node.定位问题出在Node.js进程的假死状态。这里需要注意的是,上面生成coredump的操作并不是那么安全。请记住监视和警告服务器磁盘**。在获取到Node.js应用产生的coredump文件后,我们可以使用Node.js性能平台提供的在线Coredump文件分析功能来分析定位进程崩溃的原因。具体用法将在本书图解的第二部分进行说明。小结本节从几个常见的服务器问题中,给大家一个大概的排查和定位在线Node.js应用的印象。本章也是为后续内容做一个初步的认识。理解了这部分之后,只有在后面的一些实战案例中,才能明白为什么我们忽略别人而选择对其中的一些重点进行详细分析。对coredump的深入分析可以帮助我们解决大部分Node.js应用的底层故障,因为它可以还原有问题的JavaScript代码和导致问题的参数,功能非常强大。本文作者:易君阅读原文,为云栖社区原创内容,未经允许不得转载。