简体   繁体   English

如何在Nodejs中测量事件循环阻塞?

[英]How to measure Event loop blocking in Nodejs?

I can't get real an event loop blocking time. 我无法获得真正的事件循环阻塞时间。 I have searched in Google answers ( here ), but they didn't help for me. 我已经在Google搜索中找到了答案( 在此处 ),但它们对我没有帮助。 I got different results. 我得到了不同的结果。

I have created Node/Express app. 我已经创建了Node / Express应用程序。 And try to detect event loop blocking with different tools. 并尝试使用不同的工具检测事件循环阻塞。 I used hrtime, pm2, blocked_at . 我使用hrtime,pm2, blocked_at

1 test: 1次测试:

server.js server.js

require('./routes')(app, passport, mongoData)

routes/index.js 路线/index.js

router
  .get('/articles/:articleId(\\d+)', (req, res, next) => { 
      const blockedAt = require('blocked-at')
      blockedAt((time, stack) => {
         console.log(`Blocked for ${time}ms, operation started here:`, stack)
            },  {threshold:12})

      // my blocking script
      for (let i = 0; i <= 1000000000; i++) {
          let z = 10000 / Math.random()         
      }

      let ArticleController = require(path + 'app/controllers/ArticleController')
      let articleController = new ArticleController()
      articleController.index(req, res, next)
    })

I got: 我有:

Blocked for 15.5994921875ms, operation started here: [ ' at ', ' at ArticleService.getArticle (/app/services/article/ArticleService.js:79:44)' ] Blocked for 14.0350537109375ms, operation started here: [ ' at Promise.then ()', ' at ExpressHandlebars.render (node_modules/express-handlebars/lib/express-handlebars.js:157:8)', ' at ExpressHandlebars. 阻塞了155994921875ms,操作从此处开始:['在','在ArticleService.getArticle(/app/services/article/ArticleService.js:79:44)']阻塞14.0350537109375ms,操作从此处开始:['在Promise .then()','在ExpressHandlebars.render(node_modules / express-handlebars / lib / express-handlebars.js:157:8)','在ExpressHandlebars。 (node_modules/express-handlebars/lib/express-handlebars.js:226:29)' ] (node_modules / express-handlebars / lib / express-handlebars.js:226:29)']

But nothing about my blocking script! 但是我的阻止脚本一无所获!

2 test: 2测试:

With pm2: 使用pm2:

  • Event Loop Latency - 0.56ms 事件循环延迟-0.56ms
  • Event Loop Latency p95 - 4.5ms 事件循环延迟p95-4.5ms

After remove my blocking script I get same results. 删除阻止脚本后,我得到相同的结果。

3 test: 3测试:

With hrtime I measure inside ArticleController.index. 使用hrtime,我在ArticleController.index内部进行测量。 Index method loads 3 services in async mode. 索引方法以异步模式加载3个服务。 There are a lot of I/O operations, and there works worker_threads. 有很多I / O操作,并且有worker_threads。 Some code created into setImmediate. 将一些代码创建到setImmediate中。

inside into index: 内入索引:

let hrstart = process.hrtime()

// there works all my services 
//...

let hrend = process.hrtime(hrstart)
 console.info('Execution time (hr): %ds ir ms: %dms', hrend[0], hrend[1] / 1000000)

res.render('home', data)

There I got 1s, 233ms. 在那里,我得到了1s,233ms。 I got big time, but I confused - because there all operations work in async mode, Event loop ain't blocking? 我有很多时间,但是我很困惑-因为所有操作都在异步模式下进行,所以事件循环不会阻塞吗?

How I can measure Event loop blocks? 如何测量事件循环块?

I expect the output: "event loop blocking in routes/index.js:12 for 5000ms", but actual output doesn't catch my blocking script. 我期望输出:“事件循环在route / index.js:12中阻塞5000ms”,但实际输出无法捕获我的阻塞脚本。

The amount of time you block the event loop is the amount of time you spend sequentially processing. 阻塞事件循环的时间就是顺序处理所花费的时间。 Which for your example will be the body of that function. 对于您的示例,哪个将是该函数的主体。 So you could just time that and add it on to a variable. 因此,您可以将其计时并将其添加到变量中。

let totalBlocked = 0;

router
  .get('/articles/:articleId(\\d+)', (req, res, next) => { 
      const start = new Date().getTime();

      // my blocking script
      for (let i = 0; i <= 1000000000; i++) {
          let z = 10000 / Math.random() ;        
      }

      let ArticleController = require(path + 'app/controllers/ArticleController');
      let articleController = new ArticleController();
      articleController.index(req, res, next);

      const total = new Date().getTime() - start;
      totalBlocked += total;
      console.log(`Blocked for ${total}. Total blocked time is ${totalBlocked}`);
    });

You can also use the Node perf_hooks for high resolution timing. 您也可以将Node perf_hooks用于高分辨率计时。

const {performance } = require('perf_hooks');

let totalBlocked = 0;

router
  .get('/articles/:articleId(\\d+)', (req, res, next) => { 
      const start = performance.now();
      // Do stuff
      const total = performance.now() - start;
      totalBlocked += total;
      console.log(`Blocked for ${total}. Total blocked time is ${totalBlocked}`);
   });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM