Node.js 性能平台支持死循环和正则攻击定位-阿里云开发者社区

开发者社区> 开发与运维> 正文

Node.js 性能平台支持死循环和正则攻击定位

简介: Node.js 性能平台开始支持死循环和正则攻击定位

Node.js 应用里面,常见性能问题从表现上来看有这么几类(Node.js 性能平台都提供了对应解决方案):

  • CPU 飚高:做 CPU Prfiling 定位热点函数
  • 内存泄露:堆快照/heaptimeline/heapprofile进行定位
  • CPU/内存使用都不高,但是 QPS 上不去或者 RT 很长:trace进行定位

CPU 飚高的情况又可分为两类:

  • 仍然可以继续处理业务,只是 RT 变长,这可以通过 CPU Profiling 定位
  • 完全无法继续处理业务,表现为 CPU 100% 占用,堆信息监控为直线

无法处理新业务的情况,JS 代码一般处于下面几种状态:

  • while/for 循环一直运行
  • 计算一直无法完成:例如执行一个斐波那契数列运算,当输入大于 50 的时候
  • 执行长时间正则表达式,

Node.js 性能平台在运行时v3.11.3v4.2.1及以前的版本里面对于,由于无法启动 CPU Profiling,也没有特别好的定位方法。只能根据监控提供问题开始时刻,去 nginx 的 access 日志里面查找相关线索。

随着 v3.11.4v4.2.1版本的发布,这两大难题将不会继续困扰我们。

即使代码处于上述中死循环长时间计算或者长时间正则表达式匹配状态,仍然可以启动 CPU Profiling,定位到问题所在。

下面的例子都来自不同行业的用户案例,为了简化验证过程,集成到了一个简单的 http 服务中。
默认用户已经开通 Node.js 性能服务,否则请参考 用户指南

'use strict';

const http = require('http');

function regexp() {
  let str = '<br/>                                             ' +
    '           早餐后自由活动,于指定时间集合自行办理退房手续。';
  str += '<br/>                                      <br/>' +
    '                                        <br/>           ' +
    '                         <br/>';
  str += '                                    <br/>' +
    '                                                        ' +
    '                                                        ' +
    '        <br/>';
  str += '                                                <br/>                                                                                                                <br/>';
  str += '                                                     ' +
    '                                                        ' +
    '       根据船班时间,自行前往暹粒机场,返回中国。<br/>';
  str += '如需送机服务,需增加280/每单。<br/>';

  let r = String(str).replace(/(^(\s*?<br[\s\/]*?>\*?)+|(\s*?<br[\s\/]*?>\s*?)+?$)/igm, '');
}

function deadloop () {
  while(1);
}

function f1() {
  deadloop();
}
function f2(){
  f1();
}
function f3(){
  f2();
}
function f4(){
  f3();
}

http.createServer( (req, res) => {
  console.log(req.url);

  switch(req.url) {
    case '/regexp': {
      regexp();
      res.end('regexp case');
    } break;
    case '/deadloop': {
      f4();
      res.end('deadloop case');
    } break;
    case '/exit': {
      process.exit(0);
    } break;
    default: {
      res.writeHead(200, "OK",{'Content-Type': 'text/html'});
      res.write('<html><head><title>Node.js</title></head><body style="font-family:arial;">');
      res.write('<h2> Regular Expression and Dead Loop Detection Example</h2>');

      res.write('<p>Click on button below to trigger long time running regexp test.');
      res.write('<form enctype="application/x-www-form-urlencoded" action="/regexp" method="post">');
      res.write('<button>Trigger Long Running Regular Expression</button></form>');

      res.write('<p>Click on button below to enter JavaScript dead loop test');
      res.write('<form enctype="application/x-www-form-urlencoded" action="/deadloop" method="post">');
      res.write('<button>Trigger Dead Loop JS function</button></form>');

      res.write('<p>The test can be terminated only before the above cases triggered.');
      res.write('<form enctype="application/x-www-form-urlencoded" action="/exit" method="post">');
      res.write('<button>Exit Test</button></form>');
      res.write('</form></body></html');
      res.end();
    } break;
  }
}).listen(8080);

console.log('\nhttp listen at 8080 pid: ', process.pid);

以下两幅图均是代码已经处于 CPU 100% 状态后启动 Profiling 后定位结果。

  • 正则表达式准确定位到当前执行的函数

undefined

  • 死循环目前定位到 while(1) 所在函数的调用者。如果在 CPU 100% 前启动 Profiling 则可以定位到具体函数,然而线上故障的不可预测性使得我们无法在问题出现前3分钟启动,后续 Node.js 性能平台会继续优化此处。

undefined

注意:
v3.11.4 和 v4.2.1 运行时采用了 SIGUSR2 触发诊断。如果用户没有设置 ENABLE_NODE_LOG=YES,请不要点击故障诊断按钮,否则会造成进程 crash。 其它版本没有这个问题。

版权声明:本文中所有内容均属于阿里云开发者社区所有,任何媒体、网站或个人未经阿里云开发者社区协议授权不得转载、链接、转贴或以其他方式复制发布/发表。申请授权请邮件developerteam@list.alibaba-inc.com,已获得阿里云开发者社区协议授权的媒体、网站,在转载使用时必须注明"稿件来源:阿里云开发者社区,原文作者姓名",违者本社区将依法追究责任。 如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章