Scaling NodeJS beyond the ordinary

Scaling NodeJS beyond the ordinary

These are the slides to accompany the talk I gave at JSConf Iceland 2018.

D4f441c819ce53b039b514a3a6ca4803?s=128

Abhinav Rastogi

March 02, 2018
Tweet

Transcript

  1. Scaling NodeJS Beyond the ordinary Abhinav Rastogi Lead UI Engineer

    _abhinavrastogi
  2. None
  3. 150M Registered Users 500K Phones sold in 15 seconds 200M

    Visits over 5 days during annual sale event
  4. – Andre Bondi “Scalability is the capability of a system

    to handle a growing amount of work, or its potential to be enlarged to accommodate that growth.”
  5. Why should it concern the JS community?

  6. Why should it concern the JS community? • JS is

    running on servers now • Failure is shifting to application code • Failure is better handled by devs
  7. Types of Scalability x y z Add more machines Add

    more resources Application layer
  8. Horizontal Scaling

  9. Horizontal Scaling Machine Node API

  10. Horizontal Scaling Machine Node API Machine Node ELB

  11. Vertical Scaling

  12. Vertical Scaling Machine Node API

  13. Vertical Scaling Machine Node API Node ??

  14. Application Layer Optimisations

  15. The Optimisation Cycle Load Test Find Bottleneck Fix Issues

  16. network, cpu, memory, disk

  17. network bandwidth

  18. network bandwidth

  19. 1000 kb per page 100 rps per machine 100 machines

    = 10gbps
  20. compression

  21. const app = express() app.use(compression)

  22. co-hosted nginx

  23. co-hosted nginx Machine Node Node PM2 nginx API ELB

  24. network profiling

  25. netstat / ss lsof watch

  26. everything is a file in unix!

  27. ulimit

  28. ulimit core file size (blocks, -c) 0 file size (blocks,

    -f) unlimited pending signals (-i) 32767 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 max user processes (-u) 50
  29. increase the limits / reduce the usage

  30. keep-alive header

  31. keep-alive header Object.assign(headers, { 'Connection': 'keep-alive', 'Keep-Alive': 'timeout=200' });

  32. connection pooling

  33. connection pooling const http = require('http'); fetch(url, { agent: new

    http.Agent({ keepAlive: true, maxSockets: 24 }) });
  34. ephemeral ports

  35. tcp connection states

  36. tcp connection states source: http://cnp3book.info.ucl.ac.be/1st/html/transport/transport.html

  37. tcp connection states

  38. cpu

  39. cpu profiling

  40. node --prof app.js

  41. import crypto from 'crypto'; app.get('/auth', (req, res) => { const

    hash = crypto.pbkdf2Sync(password, users[username].salt, 100, 512); if (users[username].hash.toString() === hash.toString()) { res.sendStatus(200); } else { res.sendStatus(401); } });
  42. [Summary]: ticks total nonlib name 79 0.2% 0.2% JavaScript 36703

    97.2% 99.2% C++ 7 0.0% 0.0% GC 767 2.0% Shared libraries 215 0.6% Unaccounted
  43. [C++]: ticks total nonlib name 19557 51.8% 52.9% node::crypto::PBKDF2(v8) 4510

    11.9% 12.2% _sha1_block_data_order 3165 8.4% 8.6% _malloc_zone_malloc
  44. None
  45. $ npm install -g 0x $ 0x app.js

  46. None
  47. disk

  48. memory

  49. real-time monitoring

  50. load, profile, fix, repeat!

  51. thank you @_abhinavrastogi http://tiny.cc/scalingnodejs