Содержание
- 2. NodeJS Цель проекта: «Предоставить естественную неблокирующую, событийно-ориентированную инфраструктуру для написания программ с высокой конкурентностью» (с) Ryan
- 3. NodeJS NodeJS – серверная JavaScript платформа Использует Google V8 (Chromium: Google Chrome, Chrome OS, etc.) Превращает
- 4. Для чего подходит NodeJS Много I/O + большая конкурентность RIA — «богатые» приложения API Proxy Realtime
- 5. Event loop Это цикл (libev) Это один процесс, один поток Выполняет одну задачу на один момент
- 6. Время CPU – процессорное время Интерпретация кода Бизнес-логика приложения, алгоритмы Рендеринг шаблонов I/O – время ввода/вывода
- 7. $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); //
- 8. $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); //
- 9. $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); //
- 10. callback I/O I/O CPU CPU занято свободно Blocking I/O Event Loop монолит А что если во
- 11. I/O Event loop Примерно так выглядит более реальный запрос: CPU+I/O
- 12. I/O CPU callback I/O CPU Event loop Примерно так выглядит более реальный запрос:
- 13. Event loop Примерно так выглядит более реальный запрос: I/O CPU Свободно для других задач callback I/O
- 14. Event Loop mysql.query(‘SELECT count(*) FROM users’, function(err, count) { console.log(‘There are %d users in db’, count);
- 15. Event Loop mysql.query(‘SELECT count(*) FROM users’, function(err, count) { console.log(‘There are %d users in db’, count);
- 16. Event Loop mysql.query(‘SELECT count(*) FROM users’, function(err, count) { console.log(‘There are %d users in db’, count);
- 17. $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); //
- 18. $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); //
- 19. Первый запрос Blocking I/O, 1 процесс
- 20. Второй запрос, после 10ms ожидает выполнения первого Blocking I/O, 1 процесс
- 21. Третий запрос, после 50ms ожидает выполнения первого и второго Blocking I/O, 1 процесс
- 22. Blocking I/O, 1 процесс Event loop, 1 процесс
- 23. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 0ms Пришел первый запрос, Запрашиваем I/O, освобождаемся,
- 24. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 10ms Пришел второй запрос, Запрашиваем I/O, освобождаемся,
- 25. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 50ms Пришел третий запрос, Запрашиваем I/O, освобождаемся,
- 26. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 70ms Пришел ответ на I/O первого запроса,
- 27. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 80ms Пришел ответ на I/O второго запроса,
- 28. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 100ms сallback1 завершился, запускаем callback2
- 29. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 120ms Пришел ответ на I/O третьего запроса,
- 30. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 130ms сallback2 завершился, запускаем callback3
- 31. Blocking I/O, 1 процесс Event loop, 1 процесс Время: 160ms callback3 завершился Ждем других запросов
- 32. Время CPU vs I/O RIA трэнд
- 33. Приложение my_app.js library / my_module.js node_modules / express sync narrow
- 34. Приложение my_app.js library / my_module.js node_modules / express sync narrow require.paths.unshift(‘./library’) var MyModule = require(‘my_module’) var
- 35. Приложение my_app.js library / my_module.js node_modules / express sync narrow var MyModule = function() { //
- 36. Приложение my_app.js library / my_module.js node_modules / express sync narrow require.paths.unshift(‘./library’) var MyModule = require(‘my_module’) var
- 37. Приложение my_app.js library / my_module.js node_modules / express sync narrow $ node my_app.js my module: function
- 38. Приложение my_app.js library / my_module.js node_modules / express sync narrow mongoose $ npm install mongoose
- 39. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 40. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 41. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 42. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 43. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 44. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 45. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 46. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 47. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 48. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 49. HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080)
- 50. HTTP var http = require(‘http’); http.createServer(function(req, res){ setTimeout(function(){ res.end(‘World!\n’); }, 1000); res.writeHead(200, { ‘Content-Type’ : ‘text/plain’
- 51. HTTP var http = require(‘http’); http.createServer(function(req, res){ setTimeout(function(){ res.end(‘World!\n’); }, 1000); res.writeHead(200, { ‘Content-Type’ : ‘text/plain’
- 52. HTTP var http = require(‘http’); http.createServer(function(req, res){ setTimeout(function(){ res.end(‘World!\n’); }, 1000); res.writeHead(200, { ‘Content-Type’ : ‘text/plain’
- 53. HTTP var http = require(‘http’); var i = 0; http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’
- 54. HTTP var http = require(‘http’); var i = 0; http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’
- 55. HTTP var http = require(‘http’); var i = 0; http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’
- 56. Callback-driven парадигма Ломает мозг Синтаксический шум Сложно выполнить ряд действий в определенной последовательности Необходимость вручную «пробрасывать»
- 57. Callback-driven парадигма function asyncFunction(arg1, arg2, argN, callback) { } Неблокирующая функция принимает callback последним аргументом
- 58. Callback-driven парадигма function asyncFunction(arg1, arg2, argN, callback) { } function callback(err, result1, result2, resultN) { }
- 59. Callback-driven парадигма function sum(a, b) { if (a > b) { throw new Error('a cannot be
- 60. Callback-driven парадигма function sum(a, b) { if (a > b) { throw new Error('a cannot be
- 61. Callback-driven парадигма function sum(a, b) { if (a > b) { throw new Error('a cannot be
- 62. Callback-driven парадигма try { var result = sum(2, 3); console.log('result = %d', result); } catch (err)
- 63. Callback-driven парадигма try { var result = sum(2, 3); console.log('result = %d', result); } catch (err)
- 64. Callback-driven парадигма function getUser(id, callback) { }
- 65. Callback-driven парадигма function getUser(id, callback) { } getUser(1234, function(err, user) { if (err) return console.error(err); console.log(‘user:
- 66. Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); }) } +
- 67. Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); dbConnect(config.host, function(err, db){
- 68. Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); dbConnect(config.host, function(err, db){
- 69. Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback);
- 70. Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback);
- 71. Callback-driven парадигма Error: User not found at afterDbConnect (/path/to/script.js:24:14) at /path/to/script.js:20:9 at dbConnect (/path/to/script.js:7:5) at afterReadConfig
- 72. Callback-driven парадигма Error: User not found at afterDbConnect (/path/to/script.js:24:14) at /path/to/script.js:20:9 at dbConnect (/path/to/script.js:7:5) at afterReadConfig
- 73. Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback);
- 74. Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback);
- 75. node-sync Function.prototype.sync = function(context, arguments…) Использует сопрограммы (coroutines) с++ Основан на node-fibers Позволяет писать синхронно на
- 76. var Sync = require(‘sync’); function getUser(id, callback) { Sync(function(){ var config = readConfig.sync(null, ‘config.json’); var db
- 77. var Sync = require(‘sync’); function getUser(id, callback) { Sync(function(){ var config = readConfig.sync(null, ‘config.json’); var db
- 78. var Sync = require(‘sync’); function getUser(id, callback) { Sync(function(){ var config = readConfig.sync(null, ‘config.json’); var db
- 79. var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null,
- 80. var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null,
- 81. var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null,
- 82. var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null,
- 83. var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null,
- 84. Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url);
- 85. Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url);
- 86. Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url);
- 87. Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url);
- 88. Callback-driven парадигма db.fetchRows(‘SELECT * FROM pages’, function(err, pages){ var narrow = new Narrow(10, function(page, callback){ fetchUrl(page.url,
- 89. Callback-driven парадигма db.fetchRows(‘SELECT * FROM pages’, function(err, pages){ var narrow = new Narrow(10, function(page, callback){ fetchUrl(page.url,
- 90. node-sync - использует сопрограммы (coroutines) streamline.js – транслирует код node-async – целый инструментарий для асинхронного программирования
- 91. Масштабирование Nodejs – is just node (c) Ryan Dahl
- 92. Масштабирование Nodejs – is just node (c) Ryan Dahl 1 ядро CPU = 1 nodejs процесс
- 93. Масштабирование node-cluster Расширяемый Поддержка POSIX сигналов «Горячая» перезагрузка (zero-downtime) «Аккуратное» завершение (graceful shutdown) Автоматом перезапускает мертвые
- 94. HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, {
- 95. HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, {
- 96. HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, {
- 97. HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, {
- 98. HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, {
- 99. HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, {
- 100. NodeJS + Много I/O Много Запросов + Event Loop = PROFIT
- 102. Скачать презентацию