'

NodeJS Эффективное программирование

Понравилась презентация – покажи это...





Слайд 0

NodeJS Эффективное программирование Юра Богданов технический директор и соучредитель Eventr


Слайд 1

NodeJS Цель проекта: «Предоставить естественную неблокирующую, событийно-ориентированную инфраструктуру для написания программ с высокой конкурентностью» (с) Ryan Dahl «to provide a purely evented, non-blocking infrastructure to script highly concurrent programs»


Слайд 2

NodeJS NodeJS – серверная JavaScript платформа Использует Google V8 (Chromium: Google Chrome, Chrome OS, etc.) Превращает V8 в мощную машину для серверных приложений Сливается в гармонии с философией JavaScript Молодой, но живой Event loop - неблокирующий ввод/вывод Все выполняется параллельно, кроме вашего кода


Слайд 3

Для чего подходит NodeJS Много I/O + большая конкурентность RIA — «богатые» приложения API Proxy Realtime Чаты Онлайн игры Трансляции Publish/Subscribe


Слайд 4

Event loop Это цикл (libev) Это один процесс, один поток Выполняет одну задачу на один момент времени Ожидает события параллельно (libeio, pooled threads) В каждой итерации последовательно запускает функции-колбэки из трех разных очередей: nextTick функции Таймеры (setTimeout, setInterval) Сигналы ввода/вывода (libeio) Завершает работу, если все очереди пусты


Слайд 5

Время CPU – процессорное время Интерпретация кода Бизнес-логика приложения, алгоритмы Рендеринг шаблонов I/O – время ввода/вывода Запросы в базу данных (network) Чтение файлов Чтение кэша I/O CPU


Слайд 6

<?php $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); // CPU - 30ms Упрощенный пример сценария веб-приложения На самом деле, у нас много I/O и много логики


Слайд 7

<?php $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); // CPU - 30ms CPU 30% I/O 70%


Слайд 8

<?php $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); // CPU - 30ms I/O CPU занято монолит А что если...


Слайд 9

callback I/O I/O CPU CPU занято свободно Blocking I/O Event Loop монолит А что если во время ожидания I/O заниматься друмиги полезными делами?


Слайд 10

I/O Event loop Примерно так выглядит более реальный запрос: CPU+I/O


Слайд 11

I/O CPU callback I/O CPU Event loop Примерно так выглядит более реальный запрос:


Слайд 12

Event loop Примерно так выглядит более реальный запрос: I/O CPU Свободно для других задач callback I/O CPU


Слайд 13

Event Loop mysql.query(‘SELECT count(*) FROM users’, function(err, count) { console.log(‘There are %d users in db’, count); }) console.log(‘Hello, ’); Отправка запроса в БД


Слайд 14

Event Loop mysql.query(‘SELECT count(*) FROM users’, function(err, count) { console.log(‘There are %d users in db’, count); }) console.log(‘Hello, ’); Hello, Ожидание ответа БД...


Слайд 15

Event Loop mysql.query(‘SELECT count(*) FROM users’, function(err, count) { console.log(‘There are %d users in db’, count); }) console.log(‘Hello, ’); Hello, There are 10231512 users in db Пришел ответ из БД


Слайд 16

<?php $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); // CPU - 30ms db.query('SELECT * FROM users WHERE id=1’, function(err, user) { // I/O 70ms var html = renderUser(user); // CPU – 30ms })


Слайд 17

<?php $user = $db->query('SELECT * FROM users WHERE id=1'); // I/O - 70ms $html = renderUser($user); // CPU - 30ms db.query('SELECT * FROM users WHERE id=1’, function(err, user) { // I/O 70ms var html = renderUser(user); // CPU – 30ms }) CPU 30% I/O 70%


Слайд 18

Первый запрос Blocking I/O, 1 процесс


Слайд 19

Второй запрос, после 10ms ожидает выполнения первого Blocking I/O, 1 процесс


Слайд 20

Третий запрос, после 50ms ожидает выполнения первого и второго Blocking I/O, 1 процесс


Слайд 21

Blocking I/O, 1 процесс Event loop, 1 процесс


Слайд 22

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 0ms Пришел первый запрос, Запрашиваем I/O, освобождаемся, Ждем других запросов


Слайд 23

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 10ms Пришел второй запрос, Запрашиваем I/O, освобождаемся, Ждем других запросов


Слайд 24

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 50ms Пришел третий запрос, Запрашиваем I/O, освобождаемся, Ждем других запросов


Слайд 25

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 70ms Пришел ответ на I/O первого запроса, запускаем callback1


Слайд 26

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 80ms Пришел ответ на I/O второго запроса, callback2 ожидает своей очереди


Слайд 27

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 100ms сallback1 завершился, запускаем callback2


Слайд 28

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 120ms Пришел ответ на I/O третьего запроса, callback3 ожидает своей очереди


Слайд 29

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 130ms сallback2 завершился, запускаем callback3


Слайд 30

Blocking I/O, 1 процесс Event loop, 1 процесс Время: 160ms callback3 завершился Ждем других запросов


Слайд 31

Время CPU vs I/O RIA трэнд


Слайд 32

Приложение my_app.js library / my_module.js node_modules / express sync narrow


Слайд 33

Приложение my_app.js library / my_module.js node_modules / express sync narrow require.paths.unshift(‘./library’) var MyModule = require(‘my_module’) var Sync = require(‘sync’)


Слайд 34

Приложение my_app.js library / my_module.js node_modules / express sync narrow var MyModule = function() { // … } module.exports = MyModule


Слайд 35

Приложение my_app.js library / my_module.js node_modules / express sync narrow require.paths.unshift(‘./library’) var MyModule = require(‘my_module’) var Sync = require(‘sync’) console.log(‘my module: ‘, MyModule); +


Слайд 36

Приложение my_app.js library / my_module.js node_modules / express sync narrow $ node my_app.js my module: function (){}


Слайд 37

Приложение my_app.js library / my_module.js node_modules / express sync narrow mongoose $ npm install mongoose


Слайд 38

HTTP var http = require(‘http’); http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello, World\n’); }).listen(3080) console.log(‘Server running at http://127.0.0.1:3080/’); Подключаем HTTP модуль


Слайд 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) console.log(‘Server running at http://127.0.0.1:3080/’); Создаем HTTP сервер


Слайд 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) console.log(‘Server running at http://127.0.0.1:3080/’); «вешаем» сервер на 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) console.log(‘Server running at http://127.0.0.1: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) console.log(‘Server running at http://127.0.0.1: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) console.log(‘Server running at http://127.0.0.1:3080/’); Отправляем HTTP заголовок


Слайд 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) console.log(‘Server running at http://127.0.0.1:3080/’); Отправляем HTTP тело и закрываем сокет


Слайд 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) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js


Слайд 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) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js Server running at http://127.0.0.1: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) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js Server running at http://127.0.0.1:3080/ $ curl http://127.0.0.1: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) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js Server running at http://127.0.0.1:3080/ $ curl http://127.0.0.1:3080/ Hello, World $


Слайд 49

HTTP var http = require(‘http’); http.createServer(function(req, res){ setTimeout(function(){ res.end(‘World!\n’); }, 1000); res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.write(‘Hello,\n’); }).listen(3080) console.log(‘Server running at http://127.0.0.1:3080/’); Hello сразу, World – через 1 сек + + + +


Слайд 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’ }); res.write(‘Hello,\n’); }).listen(3080) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js Server running at http://127.0.0.1:3080/ $ curl http://127.0.0.1:3080/ Hello,


Слайд 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’ }); res.write(‘Hello,\n’); }).listen(3080) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js Server running at http://127.0.0.1:3080/ $ curl http://127.0.0.1:3080/ Hello, World! $ Через секунду


Слайд 52

HTTP var http = require(‘http’); var i = 0; http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘i = ’ + i + ‘\n’); i++; }).listen(3080) console.log(‘Server running at http://127.0.0.1:3080/’); Итератор, общий для всех запросов – javascript замыкание (closure)


Слайд 53

HTTP var http = require(‘http’); var i = 0; http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘i = ’ + i + ‘\n’); i++; }).listen(3080) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js Server running at http://127.0.0.1:3080/ $ curl http://127.0.0.1:3080/ i = 0 $


Слайд 54

HTTP var http = require(‘http’); var i = 0; http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘i = ’ + i + ‘\n’); i++; }).listen(3080) console.log(‘Server running at http://127.0.0.1:3080/’); $ node my_app.js Server running at http://127.0.0.1:3080/ $ curl http://127.0.0.1:3080/ i = 0 $ curl http://127.0.0.1:3080/ i = 1 $


Слайд 55

Callback-driven парадигма Ломает мозг Синтаксический шум Сложно выполнить ряд действий в определенной последовательности Необходимость вручную «пробрасывать» ошибки Бесконечная индентация – aka «спагетти код»


Слайд 56

Callback-driven парадигма function asyncFunction(arg1, arg2, argN, callback) { } Неблокирующая функция принимает callback последним аргументом


Слайд 57

Callback-driven парадигма function asyncFunction(arg1, arg2, argN, callback) { } function callback(err, result1, result2, resultN) { } Неблокирующая функция принимает callback последним аргументом Callback принимает ошибку первым аргументом, остальные – результат


Слайд 58

Callback-driven парадигма function sum(a, b) { if (a > b) { throw new Error('a cannot be greater than b'); } return a + b; }


Слайд 59

Callback-driven парадигма function sum(a, b) { if (a > b) { throw new Error('a cannot be greater than b'); } return a + b; } function asyncSum(a, b, callback) { if (a > b) { return callback(new Error('a cannot be greater than b')); } callback(null, a + b); } + + +


Слайд 60

Callback-driven парадигма function sum(a, b) { if (a > b) { throw new Error('a cannot be greater than b'); } return a + b; } function asyncSum(a, b, callback) { if (a > b) { return callback(new Error('a cannot be greater than b')); } callback(null, a + b); } + + + throw!


Слайд 61

Callback-driven парадигма try { var result = sum(2, 3); console.log('result = %d', result); } catch (err) { console.error(err); }


Слайд 62

Callback-driven парадигма try { var result = sum(2, 3); console.log('result = %d', result); } catch (err) { console.error(err); } asyncSum(2, 3, function(err, result){ if (err) return console.error(err); console.log('result = %d', result); }) + + +


Слайд 63

Callback-driven парадигма function getUser(id, callback) { }


Слайд 64

Callback-driven парадигма function getUser(id, callback) { } getUser(1234, function(err, user) { if (err) return console.error(err); console.log(‘user: ’, user); })


Слайд 65

Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); }) } + + +


Слайд 66

Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); dbConnect(config.host, function(err, db){ 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){ if (err) return callback(err); db.getUser(id, function(err, user){ if (err) return callback(err); callback(null, user); }) }) }) } + + + +


Слайд 68

Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback); }) } function afterReadConfig(id, config, callback) { dbConnect(config.host, function(err, db){ if (err) return callback(err); db.getUser(id, function(err, user){ … }) } + + + + + + +


Слайд 69

Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback); }) } function afterReadConfig(id, config, callback) { dbConnect(config.host, function(err, db){ if (err) return callback(err); afterDbConnect(id, db, callback); }) } function afterDbConnect(id, db, callback) … + +


Слайд 70

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 (/path/to/script.js:18:5) at /path/to/script.js:13:9 at readConfig (/path/to/script.js:3:5) at getUser (/path/to/script.js:11:5) at Object.<anonymous> (/path/to/script.js:28:1) at Module._compile (module.js:404:26) at Object..js (module.js:410:10)


Слайд 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 (/path/to/script.js:18:5) at /path/to/script.js:13:9 at readConfig (/path/to/script.js:3:5) at getUser (/path/to/script.js:11:5) at Object.<anonymous> (/path/to/script.js:28:1) at Module._compile (module.js:404:26) at Object..js (module.js:410:10)


Слайд 72

Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback); }) } function afterReadConfig(id, config, callback) { dbConnect(config.host, function(err, db){ if (err) return callback(err); afterDbConnect(id, db, callback); }) } function afterDbConnect(id, db, callback) … Синтаксический шум – плата за Evented I/O


Слайд 73

Callback-driven парадигма function getUser(id, callback) { readConfig(‘config.json’, function(err, config){ if (err) return callback(err); afterReadConfig(id, config, callback); }) } function afterReadConfig(id, config, callback) { dbConnect(config.host, function(err, db){ if (err) return callback(err); afterDbConnect(id, db, callback); }) } function afterDbConnect(id, db, callback) … Синтаксический шум – плата за Evented I/O PROFIT PROFIT


Слайд 74

node-sync Function.prototype.sync = function(context, arguments…) Использует сопрограммы (coroutines) с++ Основан на node-fibers Позволяет писать синхронно на nodejs https://github.com/0ctave/node-sync https://github.com/laverdet/node-fibers


Слайд 75

var Sync = require(‘sync’); function getUser(id, callback) { Sync(function(){ var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); var user = db.getUser.sync(db, id); return user; }, callback) } Запускаем новое «волокно» (Fiber) node-sync


Слайд 76

var Sync = require(‘sync’); function getUser(id, callback) { Sync(function(){ var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); var user = db.getUser.sync(db, id); return user; }, callback) } «Волокно» вернет значение или ошибку в callback node-sync


Слайд 77

var Sync = require(‘sync’); function getUser(id, callback) { Sync(function(){ var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); var user = db.getUser.sync(db, id); return user; }, callback) } Функция readConfig вызывается синхронно и возвращает значение node-sync


Слайд 78

var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); var user = db.getUser.sync(db, id); return user; }.async() То же самое, только проще (коллбэка нет) node-sync


Слайд 79

var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); var user = db.getUser.sync(db, id); return user; }.async() node-sync getUser(1234, function(err, user) { if (err) return console.error(err); console.log(‘user: ’, user); })


Слайд 80

var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); throw new Error(‘something went wrong’); return user; }.async() node-sync getUser(1234, function(err, user) { if (err) return console.error(err); console.log(‘user: ’, user); })


Слайд 81

var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); var user = db.getUser.future(db, id); var friends = db.getUserFriends.future(db, id); return { user : user.result, friends : friends.result }; }.async() node-sync getUser и getUserFriends выполняются параллельно


Слайд 82

var Sync = require(‘sync’); function getUser(id) { var config = readConfig.sync(null, ‘config.json’); var db = dbConnect.sync(null, config.host); var user = db.getUser.future(db, id); db.getUserFriends(id, friends = new Sync.Future()); return { user : user.result, friends : friends.result }; }.async() node-sync другой способ получения «тикета» future


Слайд 83

Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url); }


Слайд 84

Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url); } OK


Слайд 85

Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url); } db.fetchRows(‘SELECT * FROM pages’, function(err, pages){ pages.forEach(function(page){ fetchUrl(page.url, function(err, contents) { }) }) }); OK


Слайд 86

Callback-driven парадигма $pages = $db->fetchRows(‘SELECT * FROM pages’); foreach ($pages as $page) { $contents = fetchUrl($page->url); } db.fetchRows(‘SELECT * FROM pages’, function(err, pages){ pages.forEach(function(page){ fetchUrl(page.url, function(err, contents) { }) }) }); x 100,000 OK


Слайд 87

Callback-driven парадигма db.fetchRows(‘SELECT * FROM pages’, function(err, pages){ var narrow = new Narrow(10, function(page, callback){ fetchUrl(page.url, function(err, contents) { }) }) narrow.pushAll(pages); }); + + + https://github.com/0ctave/node-narrow


Слайд 88

Callback-driven парадигма db.fetchRows(‘SELECT * FROM pages’, function(err, pages){ var narrow = new Narrow(10, function(page, callback){ fetchUrl(page.url, function(err, contents) { }) }) narrow.pushAll(pages); }); x10 - OK + + + x 100,000 - OK https://github.com/0ctave/node-narrow


Слайд 89

node-sync - использует сопрограммы (coroutines) streamline.js – транслирует код node-async – целый инструментарий для асинхронного программирования Ваша собственная flow-control библиотека :) Callback-driven решения? https://github.com/0ctave/node-sync https://github.com/Sage/streamlinejs https://github.com/caolan/async https://github.com/joyent/node/wiki/modules#async-flow http://www.scribd.com/doc/40366684/Nodejs-Controlling-Flow


Слайд 90

Масштабирование Nodejs – is just node (c) Ryan Dahl


Слайд 91

Масштабирование Nodejs – is just node (c) Ryan Dahl 1 ядро CPU = 1 nodejs процесс


Слайд 92

Масштабирование node-cluster Расширяемый Поддержка POSIX сигналов «Горячая» перезагрузка (zero-downtime) «Аккуратное» завершение (graceful shutdown) Автоматом перезапускает мертвые процессы Не оставляет «зомби» Автоматом определяет соличество ядер CPU Поддержка REPL Статистика PID файлы Логи https://github.com/LearnBoost/cluster


Слайд 93

HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello from ‘ + process.pid + ‘\n’); }); cluster(server).listen(3080); console.log(‘Server at http://127.0.0.1:3080/ (pid: %d)’, process.pid); Подключаем модуль cluster https://github.com/LearnBoost/cluster


Слайд 94

HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello from ‘ + process.pid + ‘\n’); }); cluster(server).listen(3080); console.log(‘Server at http://127.0.0.1:3080/ (pid: %d)’, process.pid); Оборачиваем http сервер в кластер и «вешаем» на 3080 порт https://github.com/LearnBoost/cluster


Слайд 95

HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello from ‘ + process.pid + ‘\n’); }); cluster(server).listen(3080); console.log(‘Server at http://127.0.0.1:3080/ (pid: %d)’, process.pid); Дополнительно выводим PID https://github.com/LearnBoost/cluster


Слайд 96

HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello from ‘ + process.pid + ‘\n’); }); cluster(server).listen(3080); console.log(‘Server at http://127.0.0.1:3080/ (pid: %d)’, process.pid); https://github.com/LearnBoost/cluster $ node my_app.js Server at http://127.0.0.1:3080/ (pid: 9254) Server at http://127.0.0.1:3080/ (pid: 9255) Server at http://127.0.0.1:3080/ (pid: 9256)


Слайд 97

HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello from ‘ + process.pid + ‘\n’); }); cluster(server).listen(3080); console.log(‘Server at http://127.0.0.1:3080/ (pid: %d)’, process.pid); https://github.com/LearnBoost/cluster $ node my_app.js Server at http://127.0.0.1:3080/ (pid: 9254) Server at http://127.0.0.1:3080/ (pid: 9255) Server at http://127.0.0.1:3080/ (pid: 9256) $ curl http://127.0.0.1:3080/ Hello from 9255 $


Слайд 98

HTTP Cluster var http = require(‘http’), cluster = require(‘cluster’); var server = http.createServer(function(req, res){ res.writeHead(200, { ‘Content-Type’ : ‘text/plain’ }); res.end(‘Hello from ‘ + process.pid + ‘\n’); }); cluster(server).listen(3080); console.log(‘Server at http://127.0.0.1:3080/ (pid: %d)’, process.pid); https://github.com/LearnBoost/cluster $ node my_app.js Server at http://127.0.0.1:3080/ (pid: 9254) Server at http://127.0.0.1:3080/ (pid: 9255) Server at http://127.0.0.1:3080/ (pid: 9256) $ curl http://127.0.0.1:3080/ Hello from 9255 $ curl http://127.0.0.1:3080/ Hello from 9256 $


Слайд 99

NodeJS + Много I/O Много Запросов + Event Loop = PROFIT


Слайд 100

Юра Богданов https://github.com/0ctave Github: http://twitter.com/yuriybogdanov Twitter: http://about.me/bogdanov About.me: octave@eventr.com Email: http://linkedin.com/in/yuriybogdanov LinkedIn: Спасибо за внимание.


×

HTML:





Ссылка: