Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

A New Way to Profile Node.js

24 views

Published on

Video and slides synchronized, mp3 and slide download available at URL http://bit.ly/2Ln0qAO.

Matteo Collina presents a new and straightforward way to identify bottlenecks in Node.js and beyond. Filmed at qconlondon.com.

Matteo Collina is a Principal Architect at nearForm. He spends most of his days programming in Node.js, but in the past he worked with Ruby, Java and Objective-C. He is also the author of the Node.js MQTT Broker, Mosca, the fast logger Pino and of the Fastify web framework. He is a member of the Node.js Technical Steering Committee.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

A New Way to Profile Node.js

  1. 1.   A new way   to profile  Node.js Matteo Collina
  2. 2. InfoQ.com: News & Community Site Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ profile-nodejs/ • Over 1,000,000 software developers, architects and CTOs read the site world- wide every month • 250,000 senior developers subscribe to our weekly newsletter • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • 2 dedicated podcast channels: The InfoQ Podcast, with a focus on Architecture and The Engineering Culture Podcast, with a focus on building • 96 deep dives on innovative topics packed as downloadable emags and minibooks • Over 40 new content items per week
  3. 3. Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide Presented at QCon London www.qconlondon.com
  4. 4. Maximum number of servers sales traffic dropping angry people are angry @matteocollina
  5. 5. Why is it slow? @matteocollina
  6. 6. because bottleneck @matteocollina
  7. 7. The bottleneck is internal   The Node.js process   is on fire | | | | | The bottleneck is external   Something else   is on fire Why is it slow? @matteocollina
  8. 8. Where is the bottleneck? @matteocollina
  9. 9. Finding Bottlenecks @matteocollina
  10. 10. Simulating Load @matteocollina
  11. 11. Finding Bottlenecks @matteocollina
  12. 12. Diagnostics $ npm install -g clinic @matteocollina
  13. 13. Clinic Doctor Clinic Bubbleprof Clinic Flame @matteocollina
  14. 14. Clinic Doctor Collects metrics by injecting probes Assesses health with heuristics Creates recommendations @matteocollina
  15. 15. Doctor metrics @matteocollina
  16. 16. Clinic Flame Collects metrics by CPU sampling Tracks top-of-stack frequency Creates flame graphs @matteocollina
  17. 17. Flame graphs @matteocollina
  18. 18. Clinic Bubbleprof Collects metrics using async_hooks Tracks latency between operations Creates bubble graphs @matteocollina
  19. 19. Bubble graphs @matteocollina
  20. 20. Where is the bottleneck? @matteocollina
  21. 21. Clinic Flame For internal bottlenecks | | | | | Clinic Bubbleprof For external bottlenecks @matteocollina
  22. 22. Live Hack @matteocollina
  23. 23. How can we improve the performance of our Node.js apps? @matteocollina
  24. 24. The Event Loop @matteocollina
  25. 25. ┌───────────────────────────┐ ┌─>│ timers │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ pending callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ idle, prepare │ │ └─────────────┬─────────────┘ ┌───────────────┐ │ ┌─────────────┴─────────────┐ │ incoming │ │ │ poll │<─────┤ connections, │ │ └─────────────┬─────────────┘ │ data, etc. │ │ ┌─────────────┴─────────────┐ └───────────────┘ │ │ check │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ └──┤ close callbacks │ └───────────────────────────┘ Source: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ @matteocollina
  26. 26. @matteocollina
  27. 27. The life of an event 1.  JS adds a function as a listener for an I/O event 2.  The I/O event happens 3.  The specified function is called @matteocollina
  28. 28. In Node.js, there is no parallelism of function execution. @matteocollina
  29. 29. nextTick, Promises, setImmediate 1. nextTicks are always executed before Promises and other I/O events. 2. Promises are executed synchronously and resolved asynchronously, before any other I/O events. 3. setImmediate exercise the same flow of I/O events. @matteocollina
  30. 30. The hardest concept in Node.js is to know when a chunk of code is running relative to another.   Clinicjs can help you in understanding how your Node.js application works @matteocollina
  31. 31. const http = require('http') const { promisify } = require('util') const sleep = promisify(setTimeout) http.createServer(function handle (req, res) => { sleep(20).then(() => { res.end('hello world') }, (err) => { res.statusCode = 500 res.end(JSON.stringify(err)) }) }).listen(3000) @matteocollina
  32. 32. @matteocollina
  33. 33. const http = require('http') const { promisify } = require('util') const sleep = promisify(setTimeout) async function something (req, res) { await sleep(20) res.end('hello world') } http.createServer(function handle (req, res) { something(req, res).catch((err) => { res.statusCode = 500 res.end(JSON.stringify(err)) }) }).listen(3000) @matteocollina
  34. 34. @matteocollina
  35. 35. const http = require('http') const fs = require('fs') http.createServer(function f1 (req, res) { fs.readFile(__filename, function f2 (err, buf1) { if (err) throw err fs.readFile(__filename, function f3 (err, buf2) { if (err) throw err fs.readFile(__filename, function f4 (err, buf3) { if (err) throw err res.end(Buffer.concat([buf1, buf2, buf3])) }) }) }) }).listen(3000) @matteocollina
  36. 36. @matteocollina
  37. 37. const http = require('http') const fs = require('fs') const { promisify } = require('util') const readFile = promisify(fs.readFile) async function handle (req, res) { const a = await readFile(__filename) const b = await readFile(__filename) const c = await readFile(__filename) res.end(Buffer.concat([a, b, c])) } http.createServer(function (req, res) { handle(req, res).catch((err) => { res.statusCode = 500 res.end('kaboom') }) }).listen(3000) @matteocollina
  38. 38. @matteocollina
  39. 39. const http = require('http') const fs = require('fs') const { promisify } = require('util') const readFile = promisify(fs.readFile) async function handle (req, res) { res.end(Buffer.concat(await Promise.all([ readFile(__filename), readFile(__filename), readFile(__filename) ]))) } http.createServer(function (req, res) { handle(req, res).catch((err) => { res.statusCode = 500 res.end('kaboom') }) }).listen(3000) @matteocollina
  40. 40. @matteocollina
  41. 41. Performance Considerations @matteocollina
  42. 42. As a result of a slow I/O operation,   your application increase the amount of   concurrent tasks. @matteocollina
  43. 43. A huge amount of concurrent tasks increase the memory consumption of your application. @matteocollina
  44. 44. An increase in memory consumption increase the amount of work the garbage collector (GC) needs to do on our CPU. @matteocollina
  45. 45. Under high load, the GC will steal CPU cycles from our JavaScript critical path. @matteocollina
  46. 46. Therefore, latency and throughput are connected @matteocollina
  47. 47. Parting Words @matteocollina
  48. 48. Set quantifiable performance goals The application should have a response time of 200ms or less in the 99th percentile at 100 concurrent requests per server. @matteocollina
  49. 49. Pino   High speed logging library | | | | | Fastify   High speed web framework Choose fast libraries @matteocollina
  50. 50. Beware of the rabbit hole It is not uncommon for 80% of effort to be in the final 20% of optimization work Find out what fast enough is for your given business context Remember to balance the cost of your time against savings and other business gains @matteocollina
  51. 51. You don't always have to reach.. @matteocollina
  52. 52. Do you need help   with your Node.js application?
  53. 53. Questions? @matteocollina
  54. 54. Thanks @matteocollina
  55. 55. Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ profile-nodejs/

×