Introduzione a Node.js

Post on 27-May-2015

1.556 views 3 download

description

Lezione tenuta presso la Facoltà di Ingegneria dell'Università degli Studi di Brescia

Transcript of Introduzione a Node.js

COSE CHE NON TI ASPETTI DA JAVASCRIPT: NODE.JS

Chi siamo

Luciano  Colosio  

Michele  Capra  

SA  &  Dev  @  Save  The  Mom

Dev  @  OrangeCode

@unlucio

@piccoloaiutante

Cosa vedremo oggiChe  cos’è  Node.JS

Dove  nasce

ContesB  in  cui  usarlo

Il  mondo  asincrono

Demo  Live

Deploy  su  un  servizio  free  (Heroku)

Che cos’è Node.JS

Javascirpt  runBme  basato  su  V8

Event  Driven  I/O  server-­‐side

Da dove nasce

Riprodurre  il  comportamento  in  “push”  mostrato  da  gmail

Superare  i  limit  del  one-­‐way  

BONUS DERIVATO

Le  caraUerisBche  asincrone  di  JS  permeUono  una  gesBone  piu’  comoda  dell’I/O  che  costa  molto

Da dove nasce

Costo  dell’  I/OL1-­‐cache 3  cicli

L2-­‐cache 14  cicli

RAM 250  cicli

Disco 41x10^6  cicli

Network 240x10^6  cicli

Gestire le richieste

Sincrono:  gesBsco  una  richiesta  alla  volta

Contro: ogni richiesta può (e fa!) da tappo alle altre

Gestire le richieste

Fork  del  processo

Un  processo  nuovo  per  ogni  richiesta

Contro:  non  scala  su  migliaia  di  connessioni(ameno  di  non  usare  migliaia  di  servers  ;))

Gestire le richieste

Un  Thread  nuovo  per  ogni  richiesta

Contro:  la  macchina  potrebbe  non  avere  abbastanza  thread  disponibili,  programmazione  concorrente  è  complessa,  problemi  di  memoria

Gestire le richieste

La  scelta  di  node:

Singolo  Thread

Niente  parallelizzazione  del  codice

Event Loop

La  logica  nell’eventloop  risulta  bloccante:

Devo  aUendere  che  i  task  terminino

Soluzione:

NON fare nulla nel maintherad

Utilizzare event driven development

Tutte le chiamate di I/O sono gestite come eventi asincroni, quindi non

bloccanti.

Event loop

non e' necessario pre carrozzarsi per le perfomarnces

(es: pre allocare thread per rispondere piu' velocemente).

Minor spreco di memoria/risorse

Minor rischio che il server vada in oveload

Importante!

Rispondere velocemente al client delegando a task attività che richiedono risorse ed i/o ad alta latenza

Il focus è sulla risposta nel minor tempo possibile

Async VS Sync

//  Good:  write  files  asynchronouslyfs.writeFile('message.txt',  'Hello  Node',  funcBon  (err)  {    console.log("It's  saved  and  the  server  remains  responsive!");});

//  BAD:  write  files  synchronouslyfs.writeFileSync('message.txt',  'Hello  Node');console.log("It's  saved,  but  you  just  blocked  ALL  requests!");

Esempio Architettura

Le scritture dei logs non sono piu’ un problema!

User NODE

NODE

Client Web Engine

Database

Logging facility Mass storage(big slow disk)

DB

Disk

Esempio di contesti

Web API

Realtime web services (chat, push, peppertweet)

JS: V8 in Node

Stesso motore del browser ma:

non c’è DOM

tutto gira nell’Event Loop

non c’è JQuery che tenga

programmazione asincrona

ESEMPI DI APPS

Menamo  le  mani  in  pasta  :)

App Esempio

var http = require('http');

var server = http.createServer(function (request, response) {  response.writeHead(200, {"Content-Type": "text/plain"});  response.end("Hello World\n");});

server.listen(8000);

console.log("Server running at http://127.0.0.1:8000/");

HUp  Hello  World,  la  piu’  semplice  node  app:

App Esempio

var  server  =  require('./lib/node-­‐router').getServer();

server.get("/json",  funcBon  (req,  res,  match)  {    return  {hello:  "World"};});

server.get(new  RegExp("^/(.*)$"),  funcBon  hello(req,  res,  match)  {    return  "Hello  "  +  (match  ||  "World")  +  "!";});

server.listen(8080);

Http Hello World, basta una lib ed ecco un servizio REST

App Esempio

Vi  ricordate  IRC?

NO?!?!?!

Ok,  ce  l’aspeUavamo  ;P

Oggi  ci  ispireremo  al  passato  per  un  twiUer  bot:

TWITVIA

App Esempio

hUps://github.com/unlucio/tvitvia

Get  the  code:

App Esempio: Struttura

Moduli

DescriUoreper  npm

Main  File

Heroku  ProcessFile  (opBonal)

App Esempio: npm install

Moduli  installaB

Diamogli  un  nome  sensato  :)

{   "name":  "Twitvia",   "descripBon":  "Vintage  trivia  bot",   "version":  "0.0.1",   "dependencies":  {     "twit"  :  "0.1.2",     "underscore":  "1.3.1",     "db-­‐mysql":  "0.7.6"   },   "engines":  {     "node":  ">=  0.6.0"   }

App Esempio

Ovviamente  possiamoaggiungere  directorya  nostro  piacimento

per  parB  delle  nostra  app

App Esempio: def. lib

var  Twit  =  require('twit');

module.exports  =  (funcBon(twiUerClient)  {     twiUerClient  =  funcBon(datas)  {};     twiUerClient.prototype.publishTweet  =  funcBon  (message)  {};

  twiUerClient.prototype.sendMenBon  =  funcBon  (to,  message)  {};

  twiUerClient.prototype.sendDM  =  funcBon  (to,  message)  {};     twiUerClient.prototype.followUser  =  funcBon  (user)  {};     return  twiUerClient;})();

App Esempio: use libvar  TweUerClient  =  require('./lib/twiUerClient'),

var  tClient  =  new  TweUerClient({   consumer_key:                  'getItFromTwiUer',   consumer_secret:            'getItFromTwiUer',   access_token:                  'getItFromTwiUer',   access_token_secret:    'getItFromTwiUer',});

funcBon  getCommand(tweet)  {[...]}

tClient.T.stream('user',[],  funcBon  (stream)  {    stream.on('tweet',  funcBon  (tweet)  {   getCommand(tweet)    });});

App Esempio: model objsvar  _  =  require('underscore');

module.exports  =  (funcBon(quesBons)  {     quesBons  =  funcBon(db,  tweeterClient)  {     this.db  =  db;     this.tweeterClient  =  tweeterClient;   };     quesBons.prototype.publishRandom  =  funcBon()  {};     quesBons.prototype.getRandom  =  funcBon  (quesBonsList)  {};     quesBons.prototype.selectAll  =  funcBon(callback)  {};     quesBons.prototype.setAnswered  =  funcBon(refTweetID,  callback)  {}     return  quesBons;})();

App Esempio: model objs

module.exports  =  (funcBon(answers)  {     answers  =  funcBon(db,  tweeterClient)  {     this.db  =  db;     this.tweeterClient  =  tweeterClient;   };     answers.prototype.checkMatch  =    funcBon  (refTweetID,  userAnswer,  callback)  {   };

  return  answers;})();

App Esempio: model objsmodule.exports  =  (funcBon(users)  {     users  =  funcBon(db,  tweeterClient)  {     this.db  =  db;     this.tweeterClient  =  tweeterClient;   };     users.prototype.find  =  funcBon(userName,  callback)  {};     users.prototype.add  =  funcBon(userName,  callback)  {};     users.prototype.capture  =  funcBon(userName,  callback)  {};     users.prototype.scorePoint  =  funcBon(userName,  callback)  {};     users.prototype._updateScore  =  funcBon(userID,  thePlayer,  callback){};     return  users;})();

App Esempio: togethervar  mysql  =  require('db-­‐mysql'),   TweUerClient  =  require('./lib/twiUerClient'),   Users  =  require('./model/users'),   QuesBons  =  require('./model/quesBons'),   Answers  =  require('./model/answers');

var  myDb  =  new  mysql.Database({[connecBon  datas]

});

[...]

var  tClient  =  new  TweUerClient({[api  datas]

});

var  users  =  new  Users(myDb,  tClient);var  quesBons  =  new  QuesBons(myDb,  tClient);var  answers  =  new  Answers(myDb,  tClient);

tClient.T.stream('user',[],  funcBon  (stream)  {    stream.on('tweet',  funcBon  (tweet)  {   getCommand(tweet)    });});

Deploy & hostingheroku  login

Compiliamo  il  Procfileweb:  node  <mainscript.js>

git  initgit  add  .

git  commit  -­‐m  “<commento>”heroku  create  -­‐-­‐stack  cedargit  push  heroku  masterheroku  ps:scale  web=1

Nella realta’

Un  esempio  famoso  ed  eclatante  di  uBlizzo  di  node:

Linkedin!

Dove lo usano?Linkedin  usa  node  come  middle  layer  tra  i  server  di  backend  ed  i  

client  mobile

backend server

Mobile client

NodeJs instances

Mobile Client

I 10 consigli per node.jsEvitare  il  codice  sincoronoNo  socket  polling!Non  usare  node.js  per  servire  asset  staBciDelegare  il  rendering  al  clientUsare  gzip  tra  i  vari  componenBParallelizzare  al  piu’  possibile!Se  possibile:  NO  SESSIONSUsare  moduli  binari  anzicche’  in  javascriptUsare  javascript  standard  anzicche’  librerie  faUe  per  i  clientTenere  il  codice  piccolo  e  compaUo

Grazie per l’attenzione

se  volete,  trollateci  su  twiUer@unlucio  -­‐  @piccoloaiutante

Un po’ di spam ;)

hUp://nodejsconf.ithUp://www.webdebs.org/

Cerco Dev

Scrivi  a:lucio@savethemom.com

Save the Mom cerca sviluppatori da integrare nel nostro team! :)

Skills:Web

MobileWebMobile applications

(iOS, wp7, android, balckberry)