SlideShare a Scribd company logo
1 of 183
Download to read offline
PEDROFRANCESCHI
@pedroh96
pedro@pagar.me
github.com/pedrofranceschi
Node.js no
Assuntos
• O problema
Assuntos
• O problema
• Por que Node.js?
Assuntos
• O problema
• Por que Node.js?
• Problemas de Node.js
Assuntos
• O problema
• Por que Node.js?
• Problemas de Node.js
• Node.js“the right way”
Assuntos
• O problema
• Por que Node.js?
• Problemas de Node.js
• Node.js“the right way”
• Repensando a infraestrutura (+ Microservices)
Assuntos
• O problema
• Por que Node.js?
• Problemas de Node.js
• Node.js“the right way”
• Repensando a infraestrutura (+ Microservices)
• Deployment (+ Continuous Integration)
Assuntos
• O problema
• Por que Node.js?
• Problemas de Node.js
• Node.js“the right way”
• Repensando a infraestrutura (+ Microservices)
• Deployment (+ Continuous Integration)
• Conclusões…
Assuntos
O problema
“Montar um gateway de pagamentos
amigável para desenvolvedores e
empreendedores”
“A forma mais simples de receber
pagamentos online”
API RESTful
Dashboard
Angular.js
Ruby
Node.js
Python
Java
.NET
PHP
C#
Premissas da API
• Simplicidade: RESTful + JSON
Premissas da API
• Simplicidade: RESTful + JSON
• Ambiente de testes isolado e decente
Premissas da API
• Simplicidade: RESTful + JSON
• Ambiente de testes isolado e decente
• Segurança sem comprometer simplicidade (PCI)
Premissas da API
• Simplicidade: RESTful + JSON
• Ambiente de testes isolado e decente
• Segurança sem comprometer simplicidade (PCI)
• Uptime de 99,9%
Premissas da API
• Simplicidade: RESTful + JSON
• Ambiente de testes isolado e decente
• Segurança sem comprometer simplicidade (PCI)
• Uptime de 99,9%
• Escalabilidade
Premissas da API
Por que Node.js?
Por que Node.js?
Request de transação
API RESTful
Sistema antifraude
fraude
legítimaAdquirente
(Cielo, Rede, etc)
sucesso/erro
erro
Por que Node.js?
Request de transação
API RESTful
Sistema antifraude
fraude
legítimaAdquirente
(Cielo, Rede, etc)
10.000 ms
3.000
m
s
sucesso/erro
erro
Por que Node.js?
(no nosso caso)
Por que Node.js?
(no nosso caso)
• Requests externos demorados (>1.000ms)
Por que Node.js?
(no nosso caso)
• Requests externos demorados (>1.000ms)
• I/O intenso em banco de dados
Por que Node.js?
(no nosso caso)
• Requests externos demorados (>1.000ms)
• I/O intenso em banco de dados
• Totalmente assíncrono, single thread e event-based
Por que Node.js?
(no nosso caso)
• Requests externos demorados (>1.000ms)
• I/O intenso em banco de dados
• Totalmente assíncrono, single thread e event-based
• Alta carga na aplicação
Por que Node.js?
(no nosso caso)
• Requests externos demorados (>1.000ms)
• I/O intenso em banco de dados
• Totalmente assíncrono, single thread e event-based
• Alta carga na aplicação
• Pouco processamento (sem blocking de CPU)
Por que Node.js?
(no nosso caso)
“Mas é só usar threads em qualquer
linguagem!..”
Por que Node.js?
(no nosso caso)
“Mas é só usar threads em qualquer
linguagem!..”
Não.
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1.000 threads por segundo
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1.000 threads por segundo
… se cada request leva em média 10 segundos …
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1.000 threads por segundo
… se cada request leva em média 10 segundos …
Em 9 segundos, teremos 9.000 threads
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1.000 threads por segundo
… se cada request leva em média 10 segundos …
Em 9 segundos, teremos 9.000 threads
Isso escala? :P :P :P
Por que Node.js?
(no nosso caso)
Agora, em Node.js…
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1 thread
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1 thread
… se cada request leva em média 10 segundos …
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1 thread
… se cada request leva em média 10 segundos …
Em 9 segundos, teremos 1 thread
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1 thread
… se cada request leva em média 10 segundos …
Em 9 segundos, teremos 1 thread
Isso escala? Sim.
Por que Node.js?
(no nosso caso)
1.000 requests por segundo com conexão a uma API
externa + I/O no DB = 1 thread
… se cada request leva em média 10 segundos …
Em 9 segundos, teremos 1 thread
Isso escala? Sim.
#eventloopFTW
I/O síncrona
Aplicação
Sistema operacional
I/O síncrona
Aplicação
Sistema operacional
I/O
I/O síncrona
Aplicação
Sistema operacional
I/O
I/O síncrona
Aplicação
Sistema operacional
I/O
I/O bloqueante
(aplicação travada)
I/O síncrona
Aplicação
Sistema operacional
I/O
I/O bloqueante
(aplicação travada)
I/O síncrona
Aplicação
Sistema operacional
I/O
retorno
I/O bloqueante
(aplicação travada)
I/O síncrona
Aplicação
Sistema operacional
I/O
retorno
I/O bloqueante
(aplicação travada)
I/O
retorno
I/O bloqueante
(aplicação travada)
I/O síncrona
Aplicação
Sistema operacional
I/O
retorno
I/O bloqueante
(aplicação travada)
I/O
retorno
I/O bloqueante
(aplicação travada)
I/O
retorno
I/O bloqueante
(aplicação travada)
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
I/O bloqueante
(thread travada)
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
I/O bloqueante
(thread travada)
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
I/O bloqueante
(thread travada)
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
callback
I/O bloqueante
(thread travada)
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
callback
I/O bloqueante
(thread travada)
I/O
Thread
callback
I/O bloqueante
(thread travada)
I/O“assíncrona”com threads
Aplicação
Sistema operacional
I/O
Thread
callback
I/O bloqueante
(thread travada)
I/O
Thread
callback
I/O bloqueante
(thread travada)
I/O
Thread
callback
I/O bloqueante
(thread travada)
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
I/O
callback
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
I/O
callback
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
……………………………………
I/O
callback
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
……………………………………
I/O
callback
I/O
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
…………………………………………………………………………
I/O
callback
I/O
I/O
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
…………………………………………………………………………
I/O
callback
I/O
I/O
callback
O segredo do Node.js
JavaScript (event loop)
V8
libuv
Sistema operacional
……………………………………
operações assíncronas em nível de OS
…………………………………………………………………………
I/O
callback
I/O
I/O
callback
callback
Node.js escala em I/O bloqueante, não
em utilização de CPU
(threads são boas em processamento paralelo)
Problemas de Node.js
Código assíncrono (race conditions, callback hell,
testes assíncronos, etc)
db.query("SELECT a FROM users WHERE ...;", function (err, result1) {
db.query("SELECT b FROM users WHERE ...;", function (err, result2) {
db.query("SELECT c FROM users WHERE ...;", function (err, result3) {
db.query("SELECT d FROM users WHERE ...;", function (err, result4) {
db.query("SELECT e FROM users WHERE ...;", function (err, result5) {
console.log("Finished.");
});
});
});
});
});
Um ótimo exemplo do que não fazer: callback hell.
Problemas de Node.js
Problemas de Javascript: bizarrices e facilidade em não
seguir padrões e orientação a objetos.
> 0.1+0.2
0.30000000000000004
> typeof NaN
'number'
> NaN === NaN
false
Cortesia do wtfjs.com
Problemas de Node.js
Exceptions não tratadas matam o processo.
var name = “Pedro Franceschi";
console.log("Tamanho do primeiro nome: " + name.split(" ")[0].length);
console.log("Tamanho do segundo nome: " + name.split(" ")[1].length);
Problemas de Node.js
$ node test.js
Tamanho do primeiro nome: 5
Tamanho do segundo nome: 10
Exceptions não tratadas matam o processo.
var name = “Pedro";
console.log("Tamanho do primeiro nome: " + name.split(" ")[0].length);
console.log("Tamanho do segundo nome: " + name.split(" ")[1].length);
Problemas de Node.js
$ node test.js
Tamanho do primeiro nome: 5
/private/tmp/test.js:4
console.log("Tamanho do segundo nome: " + name.split(" ")[1].length);
^
TypeError: Cannot read property 'length' of undefined
at Object.<anonymous> (/private/tmp/test.js:4:61)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
Problemas de Node.js
Problemas de Node.js
• Single thread (escalar horizontalmente e
verticalmente com múltiplas instâncias)
Problemas de Node.js
• Single thread (escalar horizontalmente e
verticalmente com múltiplas instâncias)
• Leaks de memória difíceis de detectar (back-end em
C++, variáveis globalizadas, closures, etc)
Problemas de Node.js
• Single thread (escalar horizontalmente e
verticalmente com múltiplas instâncias)
• Leaks de memória difíceis de detectar (back-end em
C++, variáveis globalizadas, closures, etc)
• Programadores front-end mexendo em back-end
(“é tudo Javascript!!”)
Problemas de Node.js
• Single thread (escalar horizontalmente e
verticalmente com múltiplas instâncias)
• Leaks de memória difíceis de detectar (back-end em
C++, variáveis globalizadas, closures, etc)
• Programadores front-end mexendo em back-end
(“é tudo Javascript!!”)
• Existe a 6 anos, porém ainda é beta (v0.12.0) - e às
vezes você precisa usar unstable em produção
Node.js“the right way”
Qualidade de vida vs. tempo usando Node
Qualidade de vida vs. tempo usando Node
Node é muito
legal!!!
Qualidade de vida vs. tempo usando Node
Node é muito
legal!!! Ops… Meu código está
ficando uma zona…
Qualidade de vida vs. tempo usando Node
Node é muito
legal!!! Ops… Meu código está
ficando uma zona…
Queria ter feito em
Rails…
Qualidade de vida vs. tempo usando Node
Node é muito
legal!!! Ops… Meu código está
ficando uma zona…
Queria ter feito em
Rails…
MVC de verdade +
Promise + Bluebird <3
Modules
Node.js “the right way”
var PI = Math.PI;
exports.area = function (r) {
return PI * r * r;
};
exports.circumference = function (r) {
return 2 * PI * r;
};
circle.js
var circle = require('./circle.js');
console.log( 'The area of a circle of radius 4 is ' + circle.area(4));
main.js
Node.js “the right way”
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
[1,2,3].indexOf(5).should.equal(-1);
})
})
describe(‘#indexOf() after one second', function(){
before(function(done){
setTimeout(function(){
done();
}, 1000);
});
it('should return -1 when the value is not present', function(){
[1,2,3].indexOf(5).should.equal(-1);
})
})
});
Testes (JavaScript quebra)
(https://github.com/visionmedia/mocha e https://github.com/visionmedia/should.js/)
Node.js “the right way”
Models (Sequelize/Mongoose)
var Transaction = Sequelize.define('Transaction', {
amount: Sequelize.INTEGER,
cost: Sequelize.FLOAT,
status: {
type: Sequelize.ENUM,
values: ['paid', 'refused', 'refunded'],
defaultValue: 'processing'
}
}, {
instanceMethods: {
calculateCost: function(status){
status = status || this.status;
if(status == 'paid') {
return 50 + (this.amount * 0.015);
}
},
},
classMethods: {
},
hooks: {
beforeUpdate: function(transaction) {
return transaction.calculateCost()
.then(function(cost) {
transaction.cost = cost;
});
}
},
});
Node.js “the right way”
Models (Sequelize/Mongoose)
var Transaction = Sequelize.define('Transaction', {
amount: Sequelize.INTEGER,
cost: Sequelize.FLOAT,
status: {
type: Sequelize.ENUM,
values: ['paid', 'refused', 'refunded'],
defaultValue: 'processing'
}
}, {
instanceMethods: {
calculateCost: function(status){
status = status || this.status;
if(status == 'paid') {
return 50 + (this.amount * 0.015);
}
},
},
classMethods: {
},
hooks: {
beforeUpdate: function(transaction) {
return transaction.calculateCost()
.then(function(cost) {
transaction.cost = cost;
});
}
},
});
Node.js “the right way”
Models (Sequelize/Mongoose)
var Transaction = Sequelize.define('Transaction', {
amount: Sequelize.INTEGER,
cost: Sequelize.FLOAT,
status: {
type: Sequelize.ENUM,
values: ['paid', 'refused', 'refunded'],
defaultValue: 'processing'
}
}, {
instanceMethods: {
calculateCost: function(status){
status = status || this.status;
if(status == 'paid') {
return 50 + (this.amount * 0.015);
}
},
},
classMethods: {
},
hooks: {
beforeUpdate: function(transaction) {
return transaction.calculateCost()
.then(function(cost) {
transaction.cost = cost;
});
}
},
});
Node.js “the right way”
Models (Sequelize/Mongoose)
var Transaction = Sequelize.define('Transaction', {
amount: Sequelize.INTEGER,
cost: Sequelize.FLOAT,
status: {
type: Sequelize.ENUM,
values: ['paid', 'refused', 'refunded'],
defaultValue: 'processing'
}
}, {
instanceMethods: {
calculateCost: function(status){
status = status || this.status;
if(status == 'paid') {
return 50 + (this.amount * 0.015);
}
},
},
classMethods: {
},
hooks: {
beforeUpdate: function(transaction) {
return transaction.calculateCost()
.then(function(cost) {
transaction.cost = cost;
});
}
},
});
Node.js “the right way”
Models (Sequelize/Mongoose)
var Transaction = Sequelize.define('Transaction', {
amount: Sequelize.INTEGER,
cost: Sequelize.FLOAT,
status: {
type: Sequelize.ENUM,
values: ['paid', 'refused', 'refunded'],
defaultValue: 'processing'
}
}, {
instanceMethods: {
calculateCost: function(status){
status = status || this.status;
if(status == 'paid') {
return 50 + (this.amount * 0.015);
}
},
},
classMethods: {
},
hooks: {
beforeUpdate: function(transaction) {
return transaction.calculateCost()
.then(function(cost) {
transaction.cost = cost;
});
}
},
});
Node.js “the right way”
Promises (Bluebird)
fs.readFile("file.json", function(err, val) {
if(err) {
console.error("unable to read file");
} else {
try {
val = JSON.parse(val);
console.log(val.success);
} catch(e) {
console.error("invalid json in file");
}
}
});
Node.js “the right way”
Promises (Bluebird)
fs.readFile("file.json", function(err, val) {
if(err) {
console.error("unable to read file");
} else {
try {
val = JSON.parse(val);
console.log(val.success);
} catch(e) {
console.error("invalid json in file");
}
}
});
Node.js “the right way”
Promises (Bluebird)
fs.readFileAsync("file.json").then(JSON.parse).then(function(val) {
console.log(val.success);
})
.catch(SyntaxError, function(e) {
console.error("invalid json in file");
})
.catch(function(e){
console.error("unable to read file")
});
Assim é bem melhor :)
Node.js “the right way”
Lodash
var lines = [
['name', 'type', 'cost'],
['iPhone', 'cellphone', '2000'],
['MacBook', 'computer', '10000'],
['iPad', 'tablet', '1500']
];
var joinedLines = [];
for(var i = 0; i < lines.length; i++) {
joinedLines.push(lines[i].join(','));
}
var csvContent = joinedLines.join('n');
name,type,cost
iPhone,cellphone,2000
MacBook,computer,10000
iPad,tablet,1500
Output
Node.js “the right way”
Lodash
var lines = [
['name', 'type', 'cost'],
['iPhone', 'cellphone', '2000'],
['MacBook', 'computer', '10000'],
['iPad', 'tablet', '1500']
];
var joinedLines = [];
for(var i = 0; i < lines.length; i++) {
joinedLines.push(lines[i].join(','));
}
var csvContent = joinedLines.join('n');
name,type,cost
iPhone,cellphone,2000
MacBook,computer,10000
iPad,tablet,1500
Output
Node.js “the right way”
Lodash
var lines = [
['name', 'type', 'cost'],
['iPhone', 'cellphone', '2000'],
['MacBook', 'computer', '10000'],
['iPad', 'tablet', '1500']
];
var joinedLines = [];
for(var i = 0; i < lines.length; i++) {
joinedLines.push(lines[i].join(','));
}
var csvContent = joinedLines.join('n');
name,type,cost
iPhone,cellphone,2000
MacBook,computer,10000
iPad,tablet,1500
Output
Node.js “the right way”
Assim é bem melhor :)
Lodash
var _ = require('lodash');
var lines = [
['name', 'type', 'cost'],
['iPhone', 'cellphone', '2000'],
['MacBook', 'computer', '10000'],
['iPad', 'tablet', '1500']
];
var csvContent = _.map(lines, function(line){
return line.join(',');
}).join('n');
name,type,cost
iPhone,cellphone,2000
MacBook,computer,10000
iPad,tablet,1500
Output
Node.js “the right way”
Node.js “the right way”
• Seguir e manter um code style (dica: Google
JavaScript Style Guide)
Node.js “the right way”
• Seguir e manter um code style (dica: Google
JavaScript Style Guide)
• Tratamento de erros consistente via Promise (evitar
que processos morram)
Node.js “the right way”
• Seguir e manter um code style (dica: Google
JavaScript Style Guide)
• Tratamento de erros consistente via Promise (evitar
que processos morram)
• Manter consistência entre as bibliotecas de Promise
(i.e. usar a mesma do wrapper do database)
Node.js “the right way”
• Seguir e manter um code style (dica: Google
JavaScript Style Guide)
• Tratamento de erros consistente via Promise (evitar
que processos morram)
• Manter consistência entre as bibliotecas de Promise
(i.e. usar a mesma do wrapper do database)
• Sem for(var i = 0; i < object.length; i++) - #lodashFTW
Node.js “the right way”
utils
Node.js “the right way”
utils
• Express.js: lightweight HTTP framework
Node.js “the right way”
utils
• Express.js: lightweight HTTP framework
• Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc.
Node.js “the right way”
utils
• Express.js: lightweight HTTP framework
• Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc.
• Mongoose: ORM de MongoDB
Node.js “the right way”
utils
• Express.js: lightweight HTTP framework
• Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc.
• Mongoose: ORM de MongoDB
• Commander: wrapper de command line
Node.js “the right way”
utils
• Express.js: lightweight HTTP framework
• Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc.
• Mongoose: ORM de MongoDB
• Commander: wrapper de command line
• Vim: melhor editor de texto :P
Repensando a infraestrutura
Infraestrutura do Pagar.me
Router
api.pagar.me
Servidor da API
(Node.js)
Ambiente de testes
(sandbox dos clientes)
Ambiente de produção
Servidor da API
(Node.js)
Infraestrutura do Pagar.me
Router
api.pagar.me
Servidor da API
(Node.js)
ElasticSearchElasticSearch
Ambiente de testes
(sandbox dos clientes)
Ambiente de produção
Servidor da API
(Node.js)
Infraestrutura do Pagar.me
Router
api.pagar.me
Servidor da API
(Node.js)
ElasticSearchElasticSearch
MySQL
(transações e dados relacionais)
MySQL
(transações e dados relacionais)
Ambiente de testes
(sandbox dos clientes)
Ambiente de produção
Servidor da API
(Node.js)
Infraestrutura do Pagar.me
Router
api.pagar.me
Servidor da API
(Node.js)
ElasticSearchElasticSearch
MySQL
(transações e dados relacionais)
MySQL
(transações e dados relacionais)
Ambiente de testes
(sandbox dos clientes)
Ambiente de produção
Servidor da API
(Node.js)
Redis
+
Redis
+
Infraestrutura do Pagar.me
Router
api.pagar.me
Servidor da API
(Node.js)
ElasticSearchElasticSearch
MySQL
(transações e dados relacionais)
MySQL
(transações e dados relacionais)
MongoDB
(dados de clientes e não relacionais)
Ambiente de testes
(sandbox dos clientes)
Ambiente de produção
Servidor da API
(Node.js)
Redis
+
Redis
+
Por que tantos bancos?
Por que tantos bancos?
• Separar dados de teste (sandbox dos clientes) dos dados de
produção
Por que tantos bancos?
• Separar dados de teste (sandbox dos clientes) dos dados de
produção
• MySQL: dados relacionais (transações, assinaturas, planos,
cartões, etc.)
Por que tantos bancos?
• Separar dados de teste (sandbox dos clientes) dos dados de
produção
• MySQL: dados relacionais (transações, assinaturas, planos,
cartões, etc.)
• MongoDB: dados não-relacionais (informações do cliente,
usuários de uma conta, etc.)
Por que tantos bancos?
• Separar dados de teste (sandbox dos clientes) dos dados de
produção
• MySQL: dados relacionais (transações, assinaturas, planos,
cartões, etc.)
• MongoDB: dados não-relacionais (informações do cliente,
usuários de uma conta, etc.)
• ElasticSearch: indexação/buscas ultra-rápidas (expondo uma
engine de buscas poderosa para os clientes)
Por que tantos bancos?
• Separar dados de teste (sandbox dos clientes) dos dados de
produção
• MySQL: dados relacionais (transações, assinaturas, planos,
cartões, etc.)
• MongoDB: dados não-relacionais (informações do cliente,
usuários de uma conta, etc.)
• ElasticSearch: indexação/buscas ultra-rápidas (expondo uma
engine de buscas poderosa para os clientes)
• Redis: fila para notificações entre serviços
Por que tantos bancos?
• Separar dados de teste (sandbox dos clientes) dos dados de
produção
• MySQL: dados relacionais (transações, assinaturas, planos,
cartões, etc.)
• MongoDB: dados não-relacionais (informações do cliente,
usuários de uma conta, etc.)
• ElasticSearch: indexação/buscas ultra-rápidas (expondo uma
engine de buscas poderosa para os clientes)
• Redis: fila para notificações entre serviços
• Não há porque se prender a uma tecnologia quando cada uma
delas resolve uma parte do seu problema
Infraestrutura do Pagar.me
Router
api.pagar.me
Servidor da API
(Node.js)
ElasticSearchElasticSearch
MySQL
(transações e dados relacionais)
MySQL
(transações e dados relacionais)
MongoDB
(dados de clientes e não relacionais)
Ambiente de testes
(sandbox dos clientes)
Ambiente de produção
Servidor da API
(Node.js)
Redis
+
Redis
+
Infraestrutura do Pagar.me
Router
api.pagar.me
Servidor da API
(Node.js)
ElasticSearchElasticSearch
MySQL
(transações e dados relacionais)
MySQL
(transações e dados relacionais)
MongoDB
(dados de clientes e não relacionais)
Ambiente de testes
(sandbox dos clientes)
Ambiente de produção
Servidor da API
(Node.js)
Redis
+
Redis
+
Microservices
Cliente
Cliente
node api.js -p 3000
node gateway.js -p 5000
Cliente
node api.js -p 3000
node gateway.js -p 5000
API RESTful (pagar.me/docs)
Cliente
node api.js -p 3000
node gateway.js -p 5000
API RESTful (pagar.me/docs)
API RESTful
(serviço interno)
Cliente
node api.js -p 3000
node gateway.js -p 5000
API RESTful (pagar.me/docs)
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P
API RESTful
(serviço interno)
Cliente
node api.js -p 3000
node gateway.js -p 5000
API RESTful (pagar.me/docs)
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P
~ 550 ms
API RESTful
(serviço interno)
Cliente
node api.js -p 3000
node gateway.js -p 5000
API RESTful (pagar.me/docs)~ 500ms
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P
~ 550 ms
API RESTful
(serviço interno)
Cliente
node api.js -p 3000
node gateway.js -p 5000
API RESTful (pagar.me/docs)~ 500ms
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms
~ 550 ms
API RESTful
(serviço interno)
Cliente
node api.js -p 3000
node gateway.js -p 5000
node hookshot.js
API RESTful (pagar.me/docs)~ 500ms
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms
~ 550 ms
API RESTful
(serviço interno)
Cliente
node api.js -p 3000
node gateway.js -p 5000
node hookshot.js
API RESTful (pagar.me/docs)~ 500ms
Redis (queue)
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms
~ 550 ms
API RESTful
(serviço interno)
Cliente
node api.js -p 3000
node gateway.js -p 5000
node hookshot.js
API RESTful (pagar.me/docs)~ 500ms
Redis (queue)
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms
~ 550 ms
API RESTful
(serviço interno)
Request HTTP para
o servidor do cliente
Cliente
node api.js -p 3000
node gateway.js -p 5000
node hookshot.js
API RESTful (pagar.me/docs)~ 500ms
Redis (queue)
XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms
~ 550 ms
API RESTful
(serviço interno)
~ 100 ms
Request HTTP para
o servidor do cliente
Deployment
Nível 1
$ node server.js
n00bz… Processo não roda em background
Nível 2
$ git pull && npm install && node server.js &
Opa… Agora tem Git, update das dependências pelo NPM e o
processo roda em background
Nível 3
$ git pull && npm install && nohup node server.js
Nohup roda o processo mesmo depois do logout do SSH
Nível 4
$ git pull && npm install && service node-server restart
Um serviço é responsável por rodar e reiniciar o processo e
salvar os logs do processo
Nível 5
$ service node-server restart
Agora o servidor de CI lida com o Git e as dependências
Servidor de Continuous Integration (CI)
+
pm2
(https://github.com/Unitech/pm2)
pm2
(https://github.com/Unitech/pm2)
• Roda e gerencia os processos do Node.js (mantém
processo rodando para sempre)
pm2
(https://github.com/Unitech/pm2)
• Roda e gerencia os processos do Node.js (mantém
processo rodando para sempre)
• Reload no código on-the-fly (zero downtime)
pm2
(https://github.com/Unitech/pm2)
• Roda e gerencia os processos do Node.js (mantém
processo rodando para sempre)
• Reload no código on-the-fly (zero downtime)
• Multi-thread e clusterização sem alterar uma linha de
código
pm2
(https://github.com/Unitech/pm2)
• Roda e gerencia os processos do Node.js (mantém
processo rodando para sempre)
• Reload no código on-the-fly (zero downtime)
• Multi-thread e clusterização sem alterar uma linha de
código
• Monitoramento e gerenciamento dos logs
pm2
(https://github.com/Unitech/pm2)
• Roda e gerencia os processos do Node.js (mantém
processo rodando para sempre)
• Reload no código on-the-fly (zero downtime)
• Multi-thread e clusterização sem alterar uma linha de
código
• Monitoramento e gerenciamento dos logs
• API RESTful + interface web
Nível 6
$ pm2 reload all
Strider é o servidor de CI e o pm2 reinicia o processo on-the-fly,
sem perder nenhum request
Strider (servidor de CI)
+
Nível 7 (ChatOps)
$ pm2 reload all
Janky é o servidor de CI, Heaven é o servidor de deployment e o
pm2 reinicia o processo on-the-fly, sem perder nenhum request
Janky (Jenkins) + Heaven + Hubot
+
ChatOps
ChatOps
• Todos os commits são testados (via Janky + Jenkins)
ChatOps
• Todos os commits são testados (via Janky + Jenkins)
• Todas as branches têm um estado (green/no-green)
ChatOps
• Todos os commits são testados (via Janky + Jenkins)
• Todas as branches têm um estado (green/no-green)
• Todas as branches green podem ser deployadas (sem
regressão)
ChatOps
• Todos os commits são testados (via Janky + Jenkins)
• Todas as branches têm um estado (green/no-green)
• Todas as branches green podem ser deployadas (sem
regressão)
• Tudo acontece integrado ao GitHub
ChatOps
• Todos os commits são testados (via Janky + Jenkins)
• Todas as branches têm um estado (green/no-green)
• Todas as branches green podem ser deployadas (sem
regressão)
• Tudo acontece integrado ao GitHub
• Deploy da branch X (via Heaven) para um servidor ou
grupo de servidores
ChatOps
• Todos os commits são testados (via Janky + Jenkins)
• Todas as branches têm um estado (green/no-green)
• Todas as branches green podem ser deployadas (sem
regressão)
• Tudo acontece integrado ao GitHub
• Deploy da branch X (via Heaven) para um servidor ou
grupo de servidores
• Tudo acontece numa sala de bate papo com todas as
pessoas relacionadas ao projeto.
$ hubot ci build pagarme-api/boleto_upgrade
$ hubot ci build pagarme-api/boleto_upgrade
$ hubot deploy pagarme-api/boleto_upgrade to prod-test/api01
$ hubot ci build pagarme-api/boleto_upgrade
$ hubot deploy pagarme-api/boleto_upgrade to prod-test/api01
$ alias sharon=hubot
$ alias sharon=hubot
$ sharon deploy pagarme-api/boleto_upgrade to prod-test/api01
$ sharon ci build pagarme-api/boleto_upgrade
Conclusões…
PEDROFRANCESCHI
@pedroh96
pedro@pagar.me
github.com/pedrofranceschi
Obrigado! :)
PEDROFRANCESCHI
@pedroh96
pedro@pagar.me
github.com/pedrofranceschi
Node.js no

More Related Content

Viewers also liked

Apresentação incentivos à inovação acate 03 04 2012
Apresentação incentivos à inovação acate 03 04 2012Apresentação incentivos à inovação acate 03 04 2012
Apresentação incentivos à inovação acate 03 04 2012Eduardo Grizendi
 
Como o elasticsearch salvou minhas buscas
Como o elasticsearch salvou minhas buscasComo o elasticsearch salvou minhas buscas
Como o elasticsearch salvou minhas buscasWaldemar Neto
 
Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...
Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...
Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...Vagner Santana
 
Rede de insights
Rede de insightsRede de insights
Rede de insightsTake a Tip
 
Treinamento Desk Research
Treinamento Desk ResearchTreinamento Desk Research
Treinamento Desk ResearchEdney Souza
 
Node.js - Devo adotar na minha empresa?
Node.js - Devo adotar na minha empresa?Node.js - Devo adotar na minha empresa?
Node.js - Devo adotar na minha empresa?Pablo Souza
 
Da Integração Contínua à Entrega Contínua apenas com ferramentas open-source
Da Integração Contínua à Entrega Contínua apenas com ferramentas open-sourceDa Integração Contínua à Entrega Contínua apenas com ferramentas open-source
Da Integração Contínua à Entrega Contínua apenas com ferramentas open-sourceRaphael Paiva
 
Arquitetura de Serviços - SOA, REST, Microservices e a plataforma .NET
Arquitetura de Serviços - SOA, REST, Microservices e a plataforma .NETArquitetura de Serviços - SOA, REST, Microservices e a plataforma .NET
Arquitetura de Serviços - SOA, REST, Microservices e a plataforma .NETRenato Groff
 
2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe Attílio
2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe Attílio2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe Attílio
2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe AttílioStartups Rio Preto
 
The TeleTech 2015 Customer Experience Benchmark Research Report
The TeleTech 2015 Customer Experience Benchmark Research ReportThe TeleTech 2015 Customer Experience Benchmark Research Report
The TeleTech 2015 Customer Experience Benchmark Research ReportElizabeth Glagowski
 
ASP.NET Core com Linux, Docker e Azure
ASP.NET Core com Linux, Docker e AzureASP.NET Core com Linux, Docker e Azure
ASP.NET Core com Linux, Docker e AzureGiovanni Bassi
 
Agência Digital: #Comofas?
Agência Digital: #Comofas?Agência Digital: #Comofas?
Agência Digital: #Comofas?Neviton Santana
 
Melhoria e Transformação Digital de Processos, Casos e Decisões
Melhoria e Transformação Digital de  Processos, Casos e DecisõesMelhoria e Transformação Digital de  Processos, Casos e Decisões
Melhoria e Transformação Digital de Processos, Casos e DecisõesMauricio Bitencourt, CBPP
 
Workshop soa, microservices e devops
Workshop soa, microservices e devopsWorkshop soa, microservices e devops
Workshop soa, microservices e devopsDiego Pacheco
 
Micro serviços com node.js
Micro serviços com node.jsMicro serviços com node.js
Micro serviços com node.jsBruno Trecenti
 
Tecnicas para la caracterizacion de materiales por rayos x
Tecnicas para la caracterizacion de materiales por rayos xTecnicas para la caracterizacion de materiales por rayos x
Tecnicas para la caracterizacion de materiales por rayos xSVMXXX
 
Vantagens e desvantagens de uma arquitetura microservices
Vantagens e desvantagens de uma arquitetura microservicesVantagens e desvantagens de uma arquitetura microservices
Vantagens e desvantagens de uma arquitetura microservicesFábio Rosato
 
Testes em uma startup do mundo financeiro
Testes em uma startup do mundo financeiroTestes em uma startup do mundo financeiro
Testes em uma startup do mundo financeiroLuiz Alberto Hespanha
 
Benchmarking ppt
Benchmarking pptBenchmarking ppt
Benchmarking pptAMARAYYA
 

Viewers also liked (20)

Apresentação incentivos à inovação acate 03 04 2012
Apresentação incentivos à inovação acate 03 04 2012Apresentação incentivos à inovação acate 03 04 2012
Apresentação incentivos à inovação acate 03 04 2012
 
Como o elasticsearch salvou minhas buscas
Como o elasticsearch salvou minhas buscasComo o elasticsearch salvou minhas buscas
Como o elasticsearch salvou minhas buscas
 
Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...
Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...
Alto desempenho e escalabilidade em aplicações web utilizando banco de dados ...
 
Rede de insights
Rede de insightsRede de insights
Rede de insights
 
Treinamento Desk Research
Treinamento Desk ResearchTreinamento Desk Research
Treinamento Desk Research
 
Node.js - Devo adotar na minha empresa?
Node.js - Devo adotar na minha empresa?Node.js - Devo adotar na minha empresa?
Node.js - Devo adotar na minha empresa?
 
Da Integração Contínua à Entrega Contínua apenas com ferramentas open-source
Da Integração Contínua à Entrega Contínua apenas com ferramentas open-sourceDa Integração Contínua à Entrega Contínua apenas com ferramentas open-source
Da Integração Contínua à Entrega Contínua apenas com ferramentas open-source
 
Arquitetura de Serviços - SOA, REST, Microservices e a plataforma .NET
Arquitetura de Serviços - SOA, REST, Microservices e a plataforma .NETArquitetura de Serviços - SOA, REST, Microservices e a plataforma .NET
Arquitetura de Serviços - SOA, REST, Microservices e a plataforma .NET
 
2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe Attílio
2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe Attílio2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe Attílio
2ª Desconferência | O Nascimento da Bloom Digital Research por Felipe Attílio
 
The TeleTech 2015 Customer Experience Benchmark Research Report
The TeleTech 2015 Customer Experience Benchmark Research ReportThe TeleTech 2015 Customer Experience Benchmark Research Report
The TeleTech 2015 Customer Experience Benchmark Research Report
 
ASP.NET Core com Linux, Docker e Azure
ASP.NET Core com Linux, Docker e AzureASP.NET Core com Linux, Docker e Azure
ASP.NET Core com Linux, Docker e Azure
 
Agência Digital: #Comofas?
Agência Digital: #Comofas?Agência Digital: #Comofas?
Agência Digital: #Comofas?
 
Melhoria e Transformação Digital de Processos, Casos e Decisões
Melhoria e Transformação Digital de  Processos, Casos e DecisõesMelhoria e Transformação Digital de  Processos, Casos e Decisões
Melhoria e Transformação Digital de Processos, Casos e Decisões
 
Workshop soa, microservices e devops
Workshop soa, microservices e devopsWorkshop soa, microservices e devops
Workshop soa, microservices e devops
 
Micro serviços com node.js
Micro serviços com node.jsMicro serviços com node.js
Micro serviços com node.js
 
Tecnicas para la caracterizacion de materiales por rayos x
Tecnicas para la caracterizacion de materiales por rayos xTecnicas para la caracterizacion de materiales por rayos x
Tecnicas para la caracterizacion de materiales por rayos x
 
Vantagens e desvantagens de uma arquitetura microservices
Vantagens e desvantagens de uma arquitetura microservicesVantagens e desvantagens de uma arquitetura microservices
Vantagens e desvantagens de uma arquitetura microservices
 
Testes em uma startup do mundo financeiro
Testes em uma startup do mundo financeiroTestes em uma startup do mundo financeiro
Testes em uma startup do mundo financeiro
 
Benchmarking ppt
Benchmarking pptBenchmarking ppt
Benchmarking ppt
 
Benchmarking Trabalho Final
Benchmarking Trabalho FinalBenchmarking Trabalho Final
Benchmarking Trabalho Final
 

Similar to Node.js no Pagar.me

Node.JS - Campus Party Brasil 2011
Node.JS - Campus Party Brasil 2011Node.JS - Campus Party Brasil 2011
Node.JS - Campus Party Brasil 2011Emerson Macedo
 
Nodejs - A performance que eu sempre quis ter
Nodejs - A performance que eu sempre quis terNodejs - A performance que eu sempre quis ter
Nodejs - A performance que eu sempre quis terEmerson Macedo
 
Node.js: 5 razões para começar a utilizar
Node.js: 5 razões para começar a utilizarNode.js: 5 razões para começar a utilizar
Node.js: 5 razões para começar a utilizarFilipe Falcão
 
TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....
TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....
TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....tdc-globalcode
 
Secomp 2011 - Node.JS - Introdução
Secomp 2011 - Node.JS - IntroduçãoSecomp 2011 - Node.JS - Introdução
Secomp 2011 - Node.JS - IntroduçãoEmerson Macedo
 
RubyMasters 2011 - Beyond Ruby with NodeJS
RubyMasters 2011 - Beyond Ruby with NodeJSRubyMasters 2011 - Beyond Ruby with NodeJS
RubyMasters 2011 - Beyond Ruby with NodeJSEmerson Macedo
 
Uma visão rápida sobre Nodejs
Uma visão rápida sobre NodejsUma visão rápida sobre Nodejs
Uma visão rápida sobre NodejsRafael Soares
 
Introdução ao Node.js - FATEC SP
Introdução ao Node.js - FATEC SPIntrodução ao Node.js - FATEC SP
Introdução ao Node.js - FATEC SPArthur Fücher
 
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010Emerson Macedo
 
AWS Meetup - Processando dados em alta escala com Node.js e AWS Lambda
AWS Meetup - Processando dados em alta escala com Node.js e AWS LambdaAWS Meetup - Processando dados em alta escala com Node.js e AWS Lambda
AWS Meetup - Processando dados em alta escala com Node.js e AWS LambdaDaniel Baptista Dias
 
Criando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & DockerCriando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & DockerGiovanni Kenji Shiroma
 
Real time com java e Node.Js
Real time com java e Node.JsReal time com java e Node.Js
Real time com java e Node.JsFabiano Modos
 
Conhecendo o Nodejs
Conhecendo o NodejsConhecendo o Nodejs
Conhecendo o NodejsCaio Cutrim
 
Docker Everywhere - MTAC Week
Docker Everywhere - MTAC WeekDocker Everywhere - MTAC Week
Docker Everywhere - MTAC WeekLuiz Carlos Faria
 
O bom, o mau, o vilão... e o node.js
O bom, o mau, o vilão... e o node.jsO bom, o mau, o vilão... e o node.js
O bom, o mau, o vilão... e o node.jsNuno Paz
 
Introdução a arquitetura Serverless na AWS
Introdução a arquitetura Serverless na AWSIntrodução a arquitetura Serverless na AWS
Introdução a arquitetura Serverless na AWSTimóteo Nascimento
 

Similar to Node.js no Pagar.me (20)

Node.JS - Campus Party Brasil 2011
Node.JS - Campus Party Brasil 2011Node.JS - Campus Party Brasil 2011
Node.JS - Campus Party Brasil 2011
 
Nodejs - A performance que eu sempre quis ter
Nodejs - A performance que eu sempre quis terNodejs - A performance que eu sempre quis ter
Nodejs - A performance que eu sempre quis ter
 
Node.js: 5 razões para começar a utilizar
Node.js: 5 razões para começar a utilizarNode.js: 5 razões para começar a utilizar
Node.js: 5 razões para começar a utilizar
 
TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....
TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....
TDC2018SP | Trilha Node.js - Melhores praticas de desempenho utilizando Node....
 
Secomp 2011 - Node.JS - Introdução
Secomp 2011 - Node.JS - IntroduçãoSecomp 2011 - Node.JS - Introdução
Secomp 2011 - Node.JS - Introdução
 
RubyMasters 2011 - Beyond Ruby with NodeJS
RubyMasters 2011 - Beyond Ruby with NodeJSRubyMasters 2011 - Beyond Ruby with NodeJS
RubyMasters 2011 - Beyond Ruby with NodeJS
 
Uma visão rápida sobre Nodejs
Uma visão rápida sobre NodejsUma visão rápida sobre Nodejs
Uma visão rápida sobre Nodejs
 
Introdução ao Node.js - FATEC SP
Introdução ao Node.js - FATEC SPIntrodução ao Node.js - FATEC SP
Introdução ao Node.js - FATEC SP
 
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010
 
AWS Meetup - Processando dados em alta escala com Node.js e AWS Lambda
AWS Meetup - Processando dados em alta escala com Node.js e AWS LambdaAWS Meetup - Processando dados em alta escala com Node.js e AWS Lambda
AWS Meetup - Processando dados em alta escala com Node.js e AWS Lambda
 
Criando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & DockerCriando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & Docker
 
Real time com java e Node.Js
Real time com java e Node.JsReal time com java e Node.Js
Real time com java e Node.Js
 
Node js
Node jsNode js
Node js
 
Middlewares ASP.NET
Middlewares ASP.NETMiddlewares ASP.NET
Middlewares ASP.NET
 
NodeJS
NodeJSNodeJS
NodeJS
 
Conhecendo o Nodejs
Conhecendo o NodejsConhecendo o Nodejs
Conhecendo o Nodejs
 
Node slide
Node slideNode slide
Node slide
 
Docker Everywhere - MTAC Week
Docker Everywhere - MTAC WeekDocker Everywhere - MTAC Week
Docker Everywhere - MTAC Week
 
O bom, o mau, o vilão... e o node.js
O bom, o mau, o vilão... e o node.jsO bom, o mau, o vilão... e o node.js
O bom, o mau, o vilão... e o node.js
 
Introdução a arquitetura Serverless na AWS
Introdução a arquitetura Serverless na AWSIntrodução a arquitetura Serverless na AWS
Introdução a arquitetura Serverless na AWS
 

Node.js no Pagar.me

  • 4. • O problema • Por que Node.js? Assuntos
  • 5. • O problema • Por que Node.js? • Problemas de Node.js Assuntos
  • 6. • O problema • Por que Node.js? • Problemas de Node.js • Node.js“the right way” Assuntos
  • 7. • O problema • Por que Node.js? • Problemas de Node.js • Node.js“the right way” • Repensando a infraestrutura (+ Microservices) Assuntos
  • 8. • O problema • Por que Node.js? • Problemas de Node.js • Node.js“the right way” • Repensando a infraestrutura (+ Microservices) • Deployment (+ Continuous Integration) Assuntos
  • 9. • O problema • Por que Node.js? • Problemas de Node.js • Node.js“the right way” • Repensando a infraestrutura (+ Microservices) • Deployment (+ Continuous Integration) • Conclusões… Assuntos
  • 11. “Montar um gateway de pagamentos amigável para desenvolvedores e empreendedores”
  • 12. “A forma mais simples de receber pagamentos online”
  • 15. • Simplicidade: RESTful + JSON Premissas da API
  • 16. • Simplicidade: RESTful + JSON • Ambiente de testes isolado e decente Premissas da API
  • 17. • Simplicidade: RESTful + JSON • Ambiente de testes isolado e decente • Segurança sem comprometer simplicidade (PCI) Premissas da API
  • 18. • Simplicidade: RESTful + JSON • Ambiente de testes isolado e decente • Segurança sem comprometer simplicidade (PCI) • Uptime de 99,9% Premissas da API
  • 19. • Simplicidade: RESTful + JSON • Ambiente de testes isolado e decente • Segurança sem comprometer simplicidade (PCI) • Uptime de 99,9% • Escalabilidade Premissas da API
  • 21. Por que Node.js? Request de transação API RESTful Sistema antifraude fraude legítimaAdquirente (Cielo, Rede, etc) sucesso/erro erro
  • 22. Por que Node.js? Request de transação API RESTful Sistema antifraude fraude legítimaAdquirente (Cielo, Rede, etc) 10.000 ms 3.000 m s sucesso/erro erro
  • 23. Por que Node.js? (no nosso caso)
  • 24. Por que Node.js? (no nosso caso) • Requests externos demorados (>1.000ms)
  • 25. Por que Node.js? (no nosso caso) • Requests externos demorados (>1.000ms) • I/O intenso em banco de dados
  • 26. Por que Node.js? (no nosso caso) • Requests externos demorados (>1.000ms) • I/O intenso em banco de dados • Totalmente assíncrono, single thread e event-based
  • 27. Por que Node.js? (no nosso caso) • Requests externos demorados (>1.000ms) • I/O intenso em banco de dados • Totalmente assíncrono, single thread e event-based • Alta carga na aplicação
  • 28. Por que Node.js? (no nosso caso) • Requests externos demorados (>1.000ms) • I/O intenso em banco de dados • Totalmente assíncrono, single thread e event-based • Alta carga na aplicação • Pouco processamento (sem blocking de CPU)
  • 29. Por que Node.js? (no nosso caso) “Mas é só usar threads em qualquer linguagem!..”
  • 30. Por que Node.js? (no nosso caso) “Mas é só usar threads em qualquer linguagem!..” Não.
  • 31. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1.000 threads por segundo
  • 32. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1.000 threads por segundo … se cada request leva em média 10 segundos …
  • 33. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1.000 threads por segundo … se cada request leva em média 10 segundos … Em 9 segundos, teremos 9.000 threads
  • 34. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1.000 threads por segundo … se cada request leva em média 10 segundos … Em 9 segundos, teremos 9.000 threads Isso escala? :P :P :P
  • 35. Por que Node.js? (no nosso caso) Agora, em Node.js…
  • 36. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1 thread
  • 37. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1 thread … se cada request leva em média 10 segundos …
  • 38. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1 thread … se cada request leva em média 10 segundos … Em 9 segundos, teremos 1 thread
  • 39. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1 thread … se cada request leva em média 10 segundos … Em 9 segundos, teremos 1 thread Isso escala? Sim.
  • 40. Por que Node.js? (no nosso caso) 1.000 requests por segundo com conexão a uma API externa + I/O no DB = 1 thread … se cada request leva em média 10 segundos … Em 9 segundos, teremos 1 thread Isso escala? Sim. #eventloopFTW
  • 44. I/O síncrona Aplicação Sistema operacional I/O I/O bloqueante (aplicação travada)
  • 45. I/O síncrona Aplicação Sistema operacional I/O I/O bloqueante (aplicação travada)
  • 47. I/O síncrona Aplicação Sistema operacional I/O retorno I/O bloqueante (aplicação travada) I/O retorno I/O bloqueante (aplicação travada)
  • 48. I/O síncrona Aplicação Sistema operacional I/O retorno I/O bloqueante (aplicação travada) I/O retorno I/O bloqueante (aplicação travada) I/O retorno I/O bloqueante (aplicação travada)
  • 58. I/O“assíncrona”com threads Aplicação Sistema operacional I/O Thread callback I/O bloqueante (thread travada) I/O Thread callback I/O bloqueante (thread travada)
  • 59. I/O“assíncrona”com threads Aplicação Sistema operacional I/O Thread callback I/O bloqueante (thread travada) I/O Thread callback I/O bloqueante (thread travada) I/O Thread callback I/O bloqueante (thread travada)
  • 60. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional
  • 61. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional I/O
  • 62. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional I/O
  • 63. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional I/O
  • 64. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional I/O
  • 65. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… I/O
  • 66. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS I/O
  • 67. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS I/O
  • 68. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS I/O
  • 69. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS I/O
  • 70. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS I/O callback
  • 71. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS I/O callback I/O
  • 72. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS …………………………………… I/O callback I/O
  • 73. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS …………………………………… I/O callback I/O I/O
  • 74. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS ………………………………………………………………………… I/O callback I/O I/O
  • 75. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS ………………………………………………………………………… I/O callback I/O I/O callback
  • 76. O segredo do Node.js JavaScript (event loop) V8 libuv Sistema operacional …………………………………… operações assíncronas em nível de OS ………………………………………………………………………… I/O callback I/O I/O callback callback
  • 77. Node.js escala em I/O bloqueante, não em utilização de CPU (threads são boas em processamento paralelo)
  • 78.
  • 79.
  • 81. Código assíncrono (race conditions, callback hell, testes assíncronos, etc) db.query("SELECT a FROM users WHERE ...;", function (err, result1) { db.query("SELECT b FROM users WHERE ...;", function (err, result2) { db.query("SELECT c FROM users WHERE ...;", function (err, result3) { db.query("SELECT d FROM users WHERE ...;", function (err, result4) { db.query("SELECT e FROM users WHERE ...;", function (err, result5) { console.log("Finished."); }); }); }); }); }); Um ótimo exemplo do que não fazer: callback hell. Problemas de Node.js
  • 82. Problemas de Javascript: bizarrices e facilidade em não seguir padrões e orientação a objetos. > 0.1+0.2 0.30000000000000004 > typeof NaN 'number' > NaN === NaN false Cortesia do wtfjs.com Problemas de Node.js
  • 83. Exceptions não tratadas matam o processo. var name = “Pedro Franceschi"; console.log("Tamanho do primeiro nome: " + name.split(" ")[0].length); console.log("Tamanho do segundo nome: " + name.split(" ")[1].length); Problemas de Node.js $ node test.js Tamanho do primeiro nome: 5 Tamanho do segundo nome: 10
  • 84. Exceptions não tratadas matam o processo. var name = “Pedro"; console.log("Tamanho do primeiro nome: " + name.split(" ")[0].length); console.log("Tamanho do segundo nome: " + name.split(" ")[1].length); Problemas de Node.js $ node test.js Tamanho do primeiro nome: 5 /private/tmp/test.js:4 console.log("Tamanho do segundo nome: " + name.split(" ")[1].length); ^ TypeError: Cannot read property 'length' of undefined at Object.<anonymous> (/private/tmp/test.js:4:61) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:901:3
  • 86. Problemas de Node.js • Single thread (escalar horizontalmente e verticalmente com múltiplas instâncias)
  • 87. Problemas de Node.js • Single thread (escalar horizontalmente e verticalmente com múltiplas instâncias) • Leaks de memória difíceis de detectar (back-end em C++, variáveis globalizadas, closures, etc)
  • 88. Problemas de Node.js • Single thread (escalar horizontalmente e verticalmente com múltiplas instâncias) • Leaks de memória difíceis de detectar (back-end em C++, variáveis globalizadas, closures, etc) • Programadores front-end mexendo em back-end (“é tudo Javascript!!”)
  • 89. Problemas de Node.js • Single thread (escalar horizontalmente e verticalmente com múltiplas instâncias) • Leaks de memória difíceis de detectar (back-end em C++, variáveis globalizadas, closures, etc) • Programadores front-end mexendo em back-end (“é tudo Javascript!!”) • Existe a 6 anos, porém ainda é beta (v0.12.0) - e às vezes você precisa usar unstable em produção
  • 90.
  • 92.
  • 93. Qualidade de vida vs. tempo usando Node
  • 94. Qualidade de vida vs. tempo usando Node Node é muito legal!!!
  • 95. Qualidade de vida vs. tempo usando Node Node é muito legal!!! Ops… Meu código está ficando uma zona…
  • 96. Qualidade de vida vs. tempo usando Node Node é muito legal!!! Ops… Meu código está ficando uma zona… Queria ter feito em Rails…
  • 97. Qualidade de vida vs. tempo usando Node Node é muito legal!!! Ops… Meu código está ficando uma zona… Queria ter feito em Rails… MVC de verdade + Promise + Bluebird <3
  • 98. Modules Node.js “the right way” var PI = Math.PI; exports.area = function (r) { return PI * r * r; }; exports.circumference = function (r) { return 2 * PI * r; }; circle.js var circle = require('./circle.js'); console.log( 'The area of a circle of radius 4 is ' + circle.area(4)); main.js
  • 99. Node.js “the right way” describe('Array', function(){ describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ [1,2,3].indexOf(5).should.equal(-1); }) }) describe(‘#indexOf() after one second', function(){ before(function(done){ setTimeout(function(){ done(); }, 1000); }); it('should return -1 when the value is not present', function(){ [1,2,3].indexOf(5).should.equal(-1); }) }) }); Testes (JavaScript quebra) (https://github.com/visionmedia/mocha e https://github.com/visionmedia/should.js/)
  • 100. Node.js “the right way” Models (Sequelize/Mongoose) var Transaction = Sequelize.define('Transaction', { amount: Sequelize.INTEGER, cost: Sequelize.FLOAT, status: { type: Sequelize.ENUM, values: ['paid', 'refused', 'refunded'], defaultValue: 'processing' } }, { instanceMethods: { calculateCost: function(status){ status = status || this.status; if(status == 'paid') { return 50 + (this.amount * 0.015); } }, }, classMethods: { }, hooks: { beforeUpdate: function(transaction) { return transaction.calculateCost() .then(function(cost) { transaction.cost = cost; }); } }, });
  • 101. Node.js “the right way” Models (Sequelize/Mongoose) var Transaction = Sequelize.define('Transaction', { amount: Sequelize.INTEGER, cost: Sequelize.FLOAT, status: { type: Sequelize.ENUM, values: ['paid', 'refused', 'refunded'], defaultValue: 'processing' } }, { instanceMethods: { calculateCost: function(status){ status = status || this.status; if(status == 'paid') { return 50 + (this.amount * 0.015); } }, }, classMethods: { }, hooks: { beforeUpdate: function(transaction) { return transaction.calculateCost() .then(function(cost) { transaction.cost = cost; }); } }, });
  • 102. Node.js “the right way” Models (Sequelize/Mongoose) var Transaction = Sequelize.define('Transaction', { amount: Sequelize.INTEGER, cost: Sequelize.FLOAT, status: { type: Sequelize.ENUM, values: ['paid', 'refused', 'refunded'], defaultValue: 'processing' } }, { instanceMethods: { calculateCost: function(status){ status = status || this.status; if(status == 'paid') { return 50 + (this.amount * 0.015); } }, }, classMethods: { }, hooks: { beforeUpdate: function(transaction) { return transaction.calculateCost() .then(function(cost) { transaction.cost = cost; }); } }, });
  • 103. Node.js “the right way” Models (Sequelize/Mongoose) var Transaction = Sequelize.define('Transaction', { amount: Sequelize.INTEGER, cost: Sequelize.FLOAT, status: { type: Sequelize.ENUM, values: ['paid', 'refused', 'refunded'], defaultValue: 'processing' } }, { instanceMethods: { calculateCost: function(status){ status = status || this.status; if(status == 'paid') { return 50 + (this.amount * 0.015); } }, }, classMethods: { }, hooks: { beforeUpdate: function(transaction) { return transaction.calculateCost() .then(function(cost) { transaction.cost = cost; }); } }, });
  • 104. Node.js “the right way” Models (Sequelize/Mongoose) var Transaction = Sequelize.define('Transaction', { amount: Sequelize.INTEGER, cost: Sequelize.FLOAT, status: { type: Sequelize.ENUM, values: ['paid', 'refused', 'refunded'], defaultValue: 'processing' } }, { instanceMethods: { calculateCost: function(status){ status = status || this.status; if(status == 'paid') { return 50 + (this.amount * 0.015); } }, }, classMethods: { }, hooks: { beforeUpdate: function(transaction) { return transaction.calculateCost() .then(function(cost) { transaction.cost = cost; }); } }, });
  • 105. Node.js “the right way” Promises (Bluebird) fs.readFile("file.json", function(err, val) { if(err) { console.error("unable to read file"); } else { try { val = JSON.parse(val); console.log(val.success); } catch(e) { console.error("invalid json in file"); } } });
  • 106. Node.js “the right way” Promises (Bluebird) fs.readFile("file.json", function(err, val) { if(err) { console.error("unable to read file"); } else { try { val = JSON.parse(val); console.log(val.success); } catch(e) { console.error("invalid json in file"); } } });
  • 107. Node.js “the right way” Promises (Bluebird) fs.readFileAsync("file.json").then(JSON.parse).then(function(val) { console.log(val.success); }) .catch(SyntaxError, function(e) { console.error("invalid json in file"); }) .catch(function(e){ console.error("unable to read file") }); Assim é bem melhor :)
  • 108. Node.js “the right way” Lodash var lines = [ ['name', 'type', 'cost'], ['iPhone', 'cellphone', '2000'], ['MacBook', 'computer', '10000'], ['iPad', 'tablet', '1500'] ]; var joinedLines = []; for(var i = 0; i < lines.length; i++) { joinedLines.push(lines[i].join(',')); } var csvContent = joinedLines.join('n'); name,type,cost iPhone,cellphone,2000 MacBook,computer,10000 iPad,tablet,1500 Output
  • 109. Node.js “the right way” Lodash var lines = [ ['name', 'type', 'cost'], ['iPhone', 'cellphone', '2000'], ['MacBook', 'computer', '10000'], ['iPad', 'tablet', '1500'] ]; var joinedLines = []; for(var i = 0; i < lines.length; i++) { joinedLines.push(lines[i].join(',')); } var csvContent = joinedLines.join('n'); name,type,cost iPhone,cellphone,2000 MacBook,computer,10000 iPad,tablet,1500 Output
  • 110. Node.js “the right way” Lodash var lines = [ ['name', 'type', 'cost'], ['iPhone', 'cellphone', '2000'], ['MacBook', 'computer', '10000'], ['iPad', 'tablet', '1500'] ]; var joinedLines = []; for(var i = 0; i < lines.length; i++) { joinedLines.push(lines[i].join(',')); } var csvContent = joinedLines.join('n'); name,type,cost iPhone,cellphone,2000 MacBook,computer,10000 iPad,tablet,1500 Output
  • 111. Node.js “the right way” Assim é bem melhor :) Lodash var _ = require('lodash'); var lines = [ ['name', 'type', 'cost'], ['iPhone', 'cellphone', '2000'], ['MacBook', 'computer', '10000'], ['iPad', 'tablet', '1500'] ]; var csvContent = _.map(lines, function(line){ return line.join(','); }).join('n'); name,type,cost iPhone,cellphone,2000 MacBook,computer,10000 iPad,tablet,1500 Output
  • 113. Node.js “the right way” • Seguir e manter um code style (dica: Google JavaScript Style Guide)
  • 114. Node.js “the right way” • Seguir e manter um code style (dica: Google JavaScript Style Guide) • Tratamento de erros consistente via Promise (evitar que processos morram)
  • 115. Node.js “the right way” • Seguir e manter um code style (dica: Google JavaScript Style Guide) • Tratamento de erros consistente via Promise (evitar que processos morram) • Manter consistência entre as bibliotecas de Promise (i.e. usar a mesma do wrapper do database)
  • 116. Node.js “the right way” • Seguir e manter um code style (dica: Google JavaScript Style Guide) • Tratamento de erros consistente via Promise (evitar que processos morram) • Manter consistência entre as bibliotecas de Promise (i.e. usar a mesma do wrapper do database) • Sem for(var i = 0; i < object.length; i++) - #lodashFTW
  • 117. Node.js “the right way” utils
  • 118. Node.js “the right way” utils • Express.js: lightweight HTTP framework
  • 119. Node.js “the right way” utils • Express.js: lightweight HTTP framework • Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc.
  • 120. Node.js “the right way” utils • Express.js: lightweight HTTP framework • Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc. • Mongoose: ORM de MongoDB
  • 121. Node.js “the right way” utils • Express.js: lightweight HTTP framework • Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc. • Mongoose: ORM de MongoDB • Commander: wrapper de command line
  • 122. Node.js “the right way” utils • Express.js: lightweight HTTP framework • Sequelize: ORM de MySQL, PostgreSQL, sqlite3, etc. • Mongoose: ORM de MongoDB • Commander: wrapper de command line • Vim: melhor editor de texto :P
  • 124. Infraestrutura do Pagar.me Router api.pagar.me Servidor da API (Node.js) Ambiente de testes (sandbox dos clientes) Ambiente de produção Servidor da API (Node.js)
  • 125. Infraestrutura do Pagar.me Router api.pagar.me Servidor da API (Node.js) ElasticSearchElasticSearch Ambiente de testes (sandbox dos clientes) Ambiente de produção Servidor da API (Node.js)
  • 126. Infraestrutura do Pagar.me Router api.pagar.me Servidor da API (Node.js) ElasticSearchElasticSearch MySQL (transações e dados relacionais) MySQL (transações e dados relacionais) Ambiente de testes (sandbox dos clientes) Ambiente de produção Servidor da API (Node.js)
  • 127. Infraestrutura do Pagar.me Router api.pagar.me Servidor da API (Node.js) ElasticSearchElasticSearch MySQL (transações e dados relacionais) MySQL (transações e dados relacionais) Ambiente de testes (sandbox dos clientes) Ambiente de produção Servidor da API (Node.js) Redis + Redis +
  • 128. Infraestrutura do Pagar.me Router api.pagar.me Servidor da API (Node.js) ElasticSearchElasticSearch MySQL (transações e dados relacionais) MySQL (transações e dados relacionais) MongoDB (dados de clientes e não relacionais) Ambiente de testes (sandbox dos clientes) Ambiente de produção Servidor da API (Node.js) Redis + Redis +
  • 129. Por que tantos bancos?
  • 130. Por que tantos bancos? • Separar dados de teste (sandbox dos clientes) dos dados de produção
  • 131. Por que tantos bancos? • Separar dados de teste (sandbox dos clientes) dos dados de produção • MySQL: dados relacionais (transações, assinaturas, planos, cartões, etc.)
  • 132. Por que tantos bancos? • Separar dados de teste (sandbox dos clientes) dos dados de produção • MySQL: dados relacionais (transações, assinaturas, planos, cartões, etc.) • MongoDB: dados não-relacionais (informações do cliente, usuários de uma conta, etc.)
  • 133. Por que tantos bancos? • Separar dados de teste (sandbox dos clientes) dos dados de produção • MySQL: dados relacionais (transações, assinaturas, planos, cartões, etc.) • MongoDB: dados não-relacionais (informações do cliente, usuários de uma conta, etc.) • ElasticSearch: indexação/buscas ultra-rápidas (expondo uma engine de buscas poderosa para os clientes)
  • 134. Por que tantos bancos? • Separar dados de teste (sandbox dos clientes) dos dados de produção • MySQL: dados relacionais (transações, assinaturas, planos, cartões, etc.) • MongoDB: dados não-relacionais (informações do cliente, usuários de uma conta, etc.) • ElasticSearch: indexação/buscas ultra-rápidas (expondo uma engine de buscas poderosa para os clientes) • Redis: fila para notificações entre serviços
  • 135. Por que tantos bancos? • Separar dados de teste (sandbox dos clientes) dos dados de produção • MySQL: dados relacionais (transações, assinaturas, planos, cartões, etc.) • MongoDB: dados não-relacionais (informações do cliente, usuários de uma conta, etc.) • ElasticSearch: indexação/buscas ultra-rápidas (expondo uma engine de buscas poderosa para os clientes) • Redis: fila para notificações entre serviços • Não há porque se prender a uma tecnologia quando cada uma delas resolve uma parte do seu problema
  • 136. Infraestrutura do Pagar.me Router api.pagar.me Servidor da API (Node.js) ElasticSearchElasticSearch MySQL (transações e dados relacionais) MySQL (transações e dados relacionais) MongoDB (dados de clientes e não relacionais) Ambiente de testes (sandbox dos clientes) Ambiente de produção Servidor da API (Node.js) Redis + Redis +
  • 137. Infraestrutura do Pagar.me Router api.pagar.me Servidor da API (Node.js) ElasticSearchElasticSearch MySQL (transações e dados relacionais) MySQL (transações e dados relacionais) MongoDB (dados de clientes e não relacionais) Ambiente de testes (sandbox dos clientes) Ambiente de produção Servidor da API (Node.js) Redis + Redis +
  • 139.
  • 141. Cliente node api.js -p 3000 node gateway.js -p 5000
  • 142. Cliente node api.js -p 3000 node gateway.js -p 5000 API RESTful (pagar.me/docs)
  • 143. Cliente node api.js -p 3000 node gateway.js -p 5000 API RESTful (pagar.me/docs) API RESTful (serviço interno)
  • 144. Cliente node api.js -p 3000 node gateway.js -p 5000 API RESTful (pagar.me/docs) XML, SOAP, ISO 8583, X25, sinal de fumaça… :P API RESTful (serviço interno)
  • 145. Cliente node api.js -p 3000 node gateway.js -p 5000 API RESTful (pagar.me/docs) XML, SOAP, ISO 8583, X25, sinal de fumaça… :P ~ 550 ms API RESTful (serviço interno)
  • 146. Cliente node api.js -p 3000 node gateway.js -p 5000 API RESTful (pagar.me/docs)~ 500ms XML, SOAP, ISO 8583, X25, sinal de fumaça… :P ~ 550 ms API RESTful (serviço interno)
  • 147. Cliente node api.js -p 3000 node gateway.js -p 5000 API RESTful (pagar.me/docs)~ 500ms XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms ~ 550 ms API RESTful (serviço interno)
  • 148. Cliente node api.js -p 3000 node gateway.js -p 5000 node hookshot.js API RESTful (pagar.me/docs)~ 500ms XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms ~ 550 ms API RESTful (serviço interno)
  • 149. Cliente node api.js -p 3000 node gateway.js -p 5000 node hookshot.js API RESTful (pagar.me/docs)~ 500ms Redis (queue) XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms ~ 550 ms API RESTful (serviço interno)
  • 150. Cliente node api.js -p 3000 node gateway.js -p 5000 node hookshot.js API RESTful (pagar.me/docs)~ 500ms Redis (queue) XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms ~ 550 ms API RESTful (serviço interno) Request HTTP para o servidor do cliente
  • 151. Cliente node api.js -p 3000 node gateway.js -p 5000 node hookshot.js API RESTful (pagar.me/docs)~ 500ms Redis (queue) XML, SOAP, ISO 8583, X25, sinal de fumaça… :P> 5000 ms ~ 550 ms API RESTful (serviço interno) ~ 100 ms Request HTTP para o servidor do cliente
  • 153. Nível 1 $ node server.js n00bz… Processo não roda em background
  • 154. Nível 2 $ git pull && npm install && node server.js & Opa… Agora tem Git, update das dependências pelo NPM e o processo roda em background
  • 155. Nível 3 $ git pull && npm install && nohup node server.js Nohup roda o processo mesmo depois do logout do SSH
  • 156. Nível 4 $ git pull && npm install && service node-server restart Um serviço é responsável por rodar e reiniciar o processo e salvar os logs do processo
  • 157. Nível 5 $ service node-server restart Agora o servidor de CI lida com o Git e as dependências Servidor de Continuous Integration (CI) +
  • 159. pm2 (https://github.com/Unitech/pm2) • Roda e gerencia os processos do Node.js (mantém processo rodando para sempre)
  • 160. pm2 (https://github.com/Unitech/pm2) • Roda e gerencia os processos do Node.js (mantém processo rodando para sempre) • Reload no código on-the-fly (zero downtime)
  • 161. pm2 (https://github.com/Unitech/pm2) • Roda e gerencia os processos do Node.js (mantém processo rodando para sempre) • Reload no código on-the-fly (zero downtime) • Multi-thread e clusterização sem alterar uma linha de código
  • 162. pm2 (https://github.com/Unitech/pm2) • Roda e gerencia os processos do Node.js (mantém processo rodando para sempre) • Reload no código on-the-fly (zero downtime) • Multi-thread e clusterização sem alterar uma linha de código • Monitoramento e gerenciamento dos logs
  • 163. pm2 (https://github.com/Unitech/pm2) • Roda e gerencia os processos do Node.js (mantém processo rodando para sempre) • Reload no código on-the-fly (zero downtime) • Multi-thread e clusterização sem alterar uma linha de código • Monitoramento e gerenciamento dos logs • API RESTful + interface web
  • 164. Nível 6 $ pm2 reload all Strider é o servidor de CI e o pm2 reinicia o processo on-the-fly, sem perder nenhum request Strider (servidor de CI) +
  • 165. Nível 7 (ChatOps) $ pm2 reload all Janky é o servidor de CI, Heaven é o servidor de deployment e o pm2 reinicia o processo on-the-fly, sem perder nenhum request Janky (Jenkins) + Heaven + Hubot +
  • 167. ChatOps • Todos os commits são testados (via Janky + Jenkins)
  • 168. ChatOps • Todos os commits são testados (via Janky + Jenkins) • Todas as branches têm um estado (green/no-green)
  • 169. ChatOps • Todos os commits são testados (via Janky + Jenkins) • Todas as branches têm um estado (green/no-green) • Todas as branches green podem ser deployadas (sem regressão)
  • 170. ChatOps • Todos os commits são testados (via Janky + Jenkins) • Todas as branches têm um estado (green/no-green) • Todas as branches green podem ser deployadas (sem regressão) • Tudo acontece integrado ao GitHub
  • 171. ChatOps • Todos os commits são testados (via Janky + Jenkins) • Todas as branches têm um estado (green/no-green) • Todas as branches green podem ser deployadas (sem regressão) • Tudo acontece integrado ao GitHub • Deploy da branch X (via Heaven) para um servidor ou grupo de servidores
  • 172. ChatOps • Todos os commits são testados (via Janky + Jenkins) • Todas as branches têm um estado (green/no-green) • Todas as branches green podem ser deployadas (sem regressão) • Tudo acontece integrado ao GitHub • Deploy da branch X (via Heaven) para um servidor ou grupo de servidores • Tudo acontece numa sala de bate papo com todas as pessoas relacionadas ao projeto.
  • 173.
  • 174. $ hubot ci build pagarme-api/boleto_upgrade
  • 175. $ hubot ci build pagarme-api/boleto_upgrade $ hubot deploy pagarme-api/boleto_upgrade to prod-test/api01
  • 176. $ hubot ci build pagarme-api/boleto_upgrade $ hubot deploy pagarme-api/boleto_upgrade to prod-test/api01 $ alias sharon=hubot
  • 177. $ alias sharon=hubot $ sharon deploy pagarme-api/boleto_upgrade to prod-test/api01 $ sharon ci build pagarme-api/boleto_upgrade
  • 178.
  • 179.
  • 181.