from:https://cnodejs.org/topic/56cc2fd6c045c3743304bec6html
Node.js 程序的运行可能会受 CPU 或输入输出操做的限制而十分缓慢。从 CPU 角度看,程序运行缓慢的典型缘由之一就是未经优化的「热点路径」(一段常常被访问的代码)。从输入输出角度看,程序运行速度的局限多是受底层操做系统影响,也多是出于 Node 自己的故障。更或者,一个运行缓慢的程序可能跟 Node 自己没有任何关系,问题在于外部资源,好比数据库查询或是 API 调用缓慢,未通过优化处理。node
在本文中,咱们将重点识别并优化代码库中会致使 CPU 繁重运行的操做。同时,将探讨生产应用的配置文件,分析并做出可提升运做效率的改动。git
因为 Node 的单线程性质,避免繁重的 CPU 负载对服务器来讲尤其重要。由于在 CPU 上消耗的时间会占用响应其余请求的时间。若是你注意到本身的应用响应速度缓慢,并且 CPU 在这个过程当中始终占用率较高,分析你的程序有助于找出瓶颈,而且使程序恢复快速运行的状态。github
##分析应用web
复制生产环境中出现的缓慢程序问题很是难解决,并且十分耗时。值得庆幸的是,你不须要亲自作这些了。你能够在生产服务器上收集配置文件数据,而后离线分析。下面让咱们来看一下几种分析方法。chrome
##一、使用内核级工具数据库
首先,你可使用内核级工具,好比 DTrace(Solaris, BSD),perf(Linux),或者 XPerf(Windows),从运行的进程中收集堆栈跟踪信息,而后生成火焰图。内核级分析对运行中的进程影响最小。火焰图是根据调用栈生成的支持放大缩小查看的向量图形。来自 Netflix 公司的 Yunong Xiao 针对 Linux 系统中 perf,发表过超赞的演讲和推文,帮助你加深对该技术的了解。若是你想在生产程序中保持高吞吐量,能够参考使用这种方法。npm
###二、使用 V8 分析器编程
另外一个选项是直接使用 V8 分析器。这种方式会与程序共享进程,所以它会影响程序性能。基于这个缘由,请只在你遇到此类问题时运行 V8 分析器来捕获相关输出。该方法的好处是:你可使用 Chrome 的全部分析工具,结合其输出结果(包括火焰图),对程序进行调查。服务器
请运行如下代码来测试你的程序:
npm install v8-profiler --save
以后,在你的程序中添加如下代码:
const profiler = require('v8-profiler') const fs = require('fs') var profilerRunning = false function toggleProfiling () { if (profilerRunning) { const profile = profiler.stopProfiling() console.log('stopped profiling') profile.export() .pipe(fs.createWriteStream('./myapp-'+Date.now()+'.cpuprofile')) .once('error', profiler.deleteAllProfiles) .once('finish', profiler.deleteAllProfiles) profilerRunning = false return } profiler.startProfiling() profilerRunning = true console.log('started profiling') } process.on('SIGUSR2', toggleProfiling)
只要你发送 SIGUSR2 信号到此进程,它就会开始分析。再次发送一个 SIGUSR2 信号能够中止分析(代码以下)。
kill -SIGUSR2 [pid]
该进程的分析结果将被写入到当前工做路径的文件中(请确保该路径可被写入)。因为这是一个可编程接口,你能够随意触发它(使用 web endpoint,IPC,等等)。若是你对程序在什么时候变得缓慢有预感,你能够在任一时期触发该接口。创建自动触发对避免持续监看程序是很是有用的,可是它要求你对捕获时间以及捕获时长有预测性认知。
一旦已经收集好配置文件数据,将它加载到Chrome开发工具中,开始分析吧!
##三、使用进程管理器
尽管直接使用 V8 分析器是很是有效且可定制的,可是它会进入你的代码库,而且会向项目添加又一项你可能不想要的依赖性条件。一种替代方式就是使用进程管理器,它能够在你须要分析时,用各类工具将你的程序包装起来。一种可选的工具是来自 StrongLoop 的 SLC 命令行工具。
首先,运行npm install strongloop –g
,而后运行如下代码:
slc start [/path/to/app]
上述代码会在进程管理器中启动你的程序,你能够按需提取 CPU 分析数据。要想验证并获取应用程序 id,请运行:
slc ctl
你将获得与下面相似的运行结果:
Service ID: 1 Service Name: my-sluggish-app Environment variables: Name Value NODE_ENV production Instances: Version Agent version Debugger version Cluster size Driver metadata 5.0.1 2.0.2 1.0.0 1 N/A Processes: ID PID WID Listening Ports Tracking objects? CPU profiling? Tracing? Debugging? 1.1.61022 61022 0 1.1.61023 61023 1 0.0.0.0:3000
定位应用的进程 id。在此例中,id 为1.1.61023。如今咱们就能在任意时间开始分析了,运行以下代码便可:
slc ctl cpu-start 1.1.61023
当咱们以为已经捕获到了迟滞行为,就能够运行如下代码来中止分析器:
slc ctl cpu-stop 1.1.61023
如下代码将写文件至硬盘:
CPU profile written to `node.1.1.61023.cpuprofile`, load into Chrome Dev Tools
好啦,就是这样。你能够像在 V8 分析器里那样把文件加载到 Chrome 里面进一步分析。
##做出正确决定
在本文中,笔者展现了三种在 Node 中捕获生产环境下 CPU 使用量的方式。那么,你应该选用哪种呢?下面是一些帮助你缩小决策范围的想法: