from:https://cnodejs.org/topic/56cc2fd6c045c3743304bec6

Node.js 程序的运行可能会受 CPU 或输入输出操作的限制而十分缓慢。从 CPU 角度看,程序运行缓慢的典型原因之一就是未经优化的「热点路径」(一段经常被访问的代码)。从输入输出角度看,程序运行速度的局限可能是受底层操作系统影响,也可能是出于 Node 本身的故障。更或者,一个运行缓慢的程序可能跟 Node 本身没有任何关系,问题在于外部资源,比如数据库查询或是 API 调用缓慢,未经过优化处理。

在本文中,我们将重点识别并优化代码库中会导致 CPU 繁重运行的操作。同时,将探讨生产应用的配置文件,分析并作出可提高运作效率的改动。

由于 Node 的单线程性质,避免繁重的 CPU 负载对服务器来说尤为重要。因为在 CPU 上消耗的时间会占用响应其他请求的时间。如果你注意到自己的应用响应速度缓慢,而且 CPU 在这个过程中始终占用率较高,分析你的程序有助于找出瓶颈,并且使程序恢复快速运行的状态。

##分析应用

复制生产环境中出现的缓慢程序问题非常难解决,而且十分耗时。值得庆幸的是,你不需要亲自做这些了。你可以在生产服务器上收集配置文件数据,然后离线分析。下面让我们来看一下几种分析方法。

##1、使用内核级工具

首先,你可以使用内核级工具,比如 DTrace(Solaris, BSD),perf(Linux),或者 XPerf(Windows),从运行的进程中收集堆栈跟踪信息,然后生成火焰图。内核级分析对运行中的进程影响最小。火焰图是根据调用栈生成的支持放大缩小查看的向量图形。来自 Netflix 公司的 Yunong Xiao 针对 Linux 系统中 perf,发表过超赞的演讲推文,帮助你加深对该技术的了解。如果你想在生产程序中保持高吞吐量,可以参考使用这种方法。

###2、使用 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开发工具中,开始分析吧!

##3、使用进程管理器

尽管直接使用 V8 分析器是非常有效且可定制的,但是它会进入你的代码库,并且会向项目添加又一项你可能不想要的依赖性条件。一种替代方式就是使用进程管理器,它可以在你需要分析时,用各种工具将你的程序包装起来。一种可选的工具是来自 StrongLoop 的 SLC 命令行工具。

首先,运行npm install strongloop –g,然后运行以下代码:

slc start [/path/to/app]

上述代码会在进程管理器中启动你的程序,你可以按需提取 CPU 分析数据。要想验证并获取应用程序 id,请运行:

slc ctl

你将得到与下面类似的运行结果:

Service ID:  Service Name: my-sluggish-app Environment variables: Name Value     NODE_ENV  production Instances: Version Agent version  Debugger version  Cluster size  Driver metadata      5.0. 2.0. 1.0.              N/A Processes:         ID      PID   WID  Listening Ports Tracking objects?  CPU profiling? Tracing? Debugging? 1.1.   1.1.   0.0.0.0:

定位应用的进程 id。在此例中,id 为1.1.61023。现在我们就能在任意时间开始分析了,运行如下代码即可:

slc ctl cpu-start 1.1.

当我们觉得已经捕获到了迟滞行为,就可以运行以下代码来停止分析器:

slc ctl cpu-stop 1.1.

以下代码将写文件至硬盘:

CPU profile written to `node.1.1.61023.cpuprofile`, load into Chrome Dev Tools

好啦,就是这样。你可以像在 V8 分析器里那样把文件加载到 Chrome 里面进一步分析。

##作出正确决定

在本文中,笔者展示了三种在 Node 中捕获生产环境下 CPU 使用量的方式。那么,你应该选用哪一种呢?下面是一些帮助你缩小决策范围的想法:

  1. 我需要分析很长一段时间:使用内核级工具。
  2. 我想用 Chrome 开发工具:使用 V8 分析器或者过程管理器。
  3. 我想捕获应用中的特定行为:使用 V8 分析器。
  4. 我不想影响到程序性能:使用内核级程序
  5. 我希望我不用挨个测试文件来获取程序分析信息:使用过程管理器。

你所未知的3种 Node.js 代码优化方式的更多相关文章

  1. Node.js——post方式提交的图片如何保存

    https://www.cnblogs.com/bruce-gou/p/6399766.html 没有使用express框架,主要是对于 request 的监听,data的时候对数据进行保存,end的 ...

  2. Node.js——body方式提交数据

    引入核心模块 http,利用其 api(http.createServer) 返回一个 http.server 实例,这个实例是继承于net.Server,net.Server 也是通过net.cre ...

  3. Linux Install Node.js

    1.下载node.js安装包,请参考网址:http://nodejs.org/download/ 在这个网址里面提供了几种node.js安装的方式 https://github.com/joyent/ ...

  4. node.js学习总结(一)

    1.1.1 安装 Node.js 有三种方式安装 Node.js:一是通过安装包安装,二是通过源码编译安装,三是在 Linux 下可以通过 yum|apt-get 安装,在 Mac 下可以通过 Hom ...

  5. 在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure

    [题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在 ...

  6. node.js如何将远程的文件下载到本地、解压、读取

    其实要解决的问题,很简单,获取远程文件,然后解压到本地读取. 在vscode中通过node.js来实现是比较方便的,相比之前的zip.js,我觉得我还是比较喜欢node.js实现方式. test.js ...

  7. JS——三种嵌入页面的方式

    一 行间事件 二 页面script标签嵌入 三 外部引入 <!DOCTYPE html> <html lang="en"> <head> < ...

  8. 在CentOS 7上安装Node.js的4种方法(包含npm)

    Node.js和Javascript有着千丝万缕的联系,可以说Node.js让Javascript显得从未如此强大.好吧…微魔其实是个门外汉…但是这并不能阻碍微魔学习探索未知的信心~今天在国外闲逛,看 ...

  9. Node.js写文件的三种方法

    Node.js写文件的三种方式: 1.通过管道流写文件 采用管道传输二进制流,可以实现自动管理流,可写流不必当心可读流流的过快而崩溃,适合大小文件传输(推荐) var readStream = fs. ...

随机推荐

  1. 浅谈FloatingActionButton(悬浮按钮)

    一.介绍 这个类是继承自ImageView的,所以对于这个控件我们可以使用ImageView的所有属性 android.support.design.widget.FloatingActionButt ...

  2. iOS 播放GIF动态图片!!!!!

    ////////////////////////////////////////////////////////////////////////////////////////// ////  Vie ...

  3. ios 颜色转图片

    - (UIImage *)imageWithColor:(UIColor*) color{    CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);    ...

  4. 优化MySchool数据库(二)

    优化School数据库(TSQL建库建表建约束) 使用T_sql代码建库.建表.建约束: 建库: Create database HotelManagerSystem on ( ---- 数据文件-- ...

  5. iOS---UISearchBar限制输入字数

    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText // called when text ...

  6. iOS通讯录开发

    场景一:直接选择一个联系人的电话号码 这里不需要先获取所有的联系人自己做联系人列表,直接使用系统自带的AddressBookUI/ABPeoplePickerNavigationController. ...

  7. HTTP和GET/POST请求(NSURLConnection)

    网络编程 网络编程是一种实时更新应用数据的常用手段 网络编程是开发优秀网络应用的前提和基础 网络基本概念 客户端(就是手机或者ipad等手持设备上面的APP) 服务器(远程服务器-本地服务器) 请求( ...

  8. Content-Type: application/vnd.ms-excel">

    如果要将查询结果导出到Excel,只需将页面的Context-Type修改一下就可以了:   header( "Content-Type: application/vnd.ms-excel& ...

  9. 一次进程hang住问题分析。。。

    这两天有同学使用数据校验工具时发现进程hang住了,也不知道什么原因,我简单看了看进程堆栈,问题虽然很简单,但能导致程序hang住,也一定不是小问题.简单说明下程序组件的结构,程序由两部分构成,dbc ...

  10. 【Html5】Html5新特性Notification实现桌面消息推送(2016-05-25)

    序:最近工作使用WorkTile,发现使用Chrome浏览器的时候如果有任务下发给我则会在桌面右下角提示(当前浏览器为最小化模式).感觉这个东西蛮有意思的,感觉可以给用户更好的体验,于是乎就查询了一下 ...