ݺߣ

ݺߣShare a Scribd company logo
JESTEM TOMEK
… i lubię dzielić się wiedzą :)
“premature optimization
is the root of all evil”
~Donald Knuth .
Tomek Banasiak: Jak bez stresu obserwować rosnący ruch w Twojej usłudze? Czyli o skalowaniu aplikacji w Node.js - RST CodeMeeting
TWÓJ
FRAMEWORK
JEST SZYBKI
WIĘKSZOŚĆ PROBLEMÓW TO
BAZA DANYCH / OPERACJE IO
CO TAK
NAPRAWDĘ JEST
CELEM
SKALOWANIA
Tylko liczba potencjalnych req/s?
● Obsługa większej ilości użytkowników
● Relacja kosztów do skali
● Odporność na awarie sprzętowe
● Odporność na awarie sieciowe
● Odporność na ataki hakerskie
● Aktualizacje aplikacji bez downtime
● Zachowanie łatwego utrzymania
aplikacji
SKALOWANIE
INFRASTRUKTUR
Y
Wertykalnie, horyzontalnie,
dekompozycja
SKALOWANIE WERTYKALNE
SKALOWANIE WERTYKALNE
● Downtime
● SPOF
● Skalowanie z limitem
● Koszty wydajniejszych maszyn
.... a chmura?
● … też downtime :)
● Koszty
● Bez architektury też skalowanie z limitem
SKALOWANIE HORYZONTALNE
HAPROXY
SKALOWANIE HORYZONTALNE
PLUSY
MINUSY
● Likwidacja SPOF
● Aktualizacja bez downtime
● Relatywnie proste i szybkie do
wykonania
● Na początku nie wymaga zmiany kodu
● Stateful apps
● Sesje
● Pliki lokalne
● Utrzymanie aplikacji
DEKOMPOZYCJA
app0 db0
DEKOMPOZYCJA
HAPROXY
KONKLUZJA
BEZ ARCHITEKTURY
APLIKACJI NIE MA
DOBREGO SKALOWANIA
SKALOWANIE
APLIKACJI
NODE.JS
Zobaczmy jak to zrobić :)
SKALOWANIE W
NODE.JS
● Asynchroniczność Twoim
przyjacielem!
● Promise’y dobrze się skalują
● Architektura oparta na
zdarzeniach
● Jednowątkowość
● Low MEM/CPU footprint
● Redis Pub/Sub, RabbitMQ, ...
CLUSTER
.JS
// cluster.js
const cluster = require('cluster');
const os = require('os');
if (cluster.isMaster) {
const cpus = os.cpus().length;
console.log(`Forking for ${cpus} CPUs`);
for (let i = 0; i<cpus; i++) {
cluster.fork();
}
} else {
require('./server');
}
CLUSTER.JS NODE MODULE
Object.values(cluster.workers).forEach(worker => {
worker.send(`Hello, worker ${worker.id}`);
});
CLUSTER.JS NODE MODULE
process.on('message', msg => {
console.log(`Message from master: ${msg}`);
});
cluster.on('exit', (worker, code, signal) => {
if (code !== 0 && !worker.exitedAfterDisconnect) {
console.log(`Worker ${worker.id} crashed. ` +
'Starting a new worker...');
cluster.fork();
}
});
const http = require('http');
const pid = process.pid;
http.createServer((req, res) => {
for (let i=0; i<1e7; i++); // fake job done
res.end(`Request handled by process ${pid}`);
}).listen(8080, () => {
console.log(`Started process ${pid}`);
});
CLUSTER.JS
node server.js node cluster.js
55 req/s 216 req/s
Test na Intel Core i5: ab -c200 -t10 http://localhost:8080/
CLUSTER.JS
● Prosty… na początku :)
● Brak zarządzania workerami
● Słaba wydajność
● APP WORKER
● Natywne wsparcie
● Aktualizacje workerów
● Skalowanie w obrębie maszyny
PM2
PM2
pm2 start server.js -i max
pm2 reload all
pm2 monit/ls
PM2
https://keymetrics.io
const http = require('http');
const pid = process.pid;
http.createServer((req, res) => {
for (let i=0; i<1e7; i++); // fake job done
res.end(`Request handled by process ${pid}`);
}).listen(8080, () => {
console.log(`Started process ${pid}`);
});
PM2
node server.js pm2 start server.js -i MAX
54 req/s 244 req/s
Test na Intel Core i5: ab -c200 -t10 http://localhost:8080/
PM2
● Sprawdzony przez społeczność
● Zarządza workerami
● Wydajność
● Aktualizacje workerów
● Integracja z narzędziami do
monitoringu
● Skalowanie na wiele maszyn
JEŚLI NIE
WORKERY TO
MIKROUSŁUGI
COTE.J
S“An auto-discovery mesh network framework for building fault-
tolerant and scalable applications”
const cote = require('cote');
const timeService = new cote.Responder({name: 'Time Service'});
timeService.on('time', (request, callback) => {
callback(new Date());
});
COTE.JS
const cote = require('cote');
const client = new cote.Requester({name: 'Client'});
client.send({type: 'time'}, (time) => {
console.log(time);
});
time-service.js
client.js
COTE.JS
● Zeroconf + dużo magii
● Działa na wielu maszynach
● COTE + PM2 = 💜
● Monitoring
● Wymaga obsługi IP
broadcast/multicast
● Chaos przy developerce
● Docker-friendly
… I CO DALEJ? :)
JAK ZAPEWNIĆ SOBIE
SPOKOJNY SEN
… I CO DALEJ? :)
● Każdy element infrastruktury może
zawieść (i zawiedzie :) )
● Skalowanie powinno być liniowe
● Znaj swój limit!
CO Z
INFRASTRUKTURĄ?
PYTANIA? ;-)
Możecie mnie znaleźć tutaj:
http://banasiak.pro
FRONTEND
BACKEND
FRONTEND MESSAGE BUS
REACT REACT REACT JS OLD JS/HTML
WebSocket connection
BACKEND GATEWAY
SERVICE 1 SERVICE 2 SERVICE 3
MESSAGE BROKER
AUTHORIZATIO
N
ROLE&ACCESSE
S
USERS
SERVICE 4 SERVICE 5
Tomek Banasiak: Jak bez stresu obserwować rosnący ruch w Twojej usłudze? Czyli o skalowaniu aplikacji w Node.js - RST CodeMeeting

More Related Content

Tomek Banasiak: Jak bez stresu obserwować rosnący ruch w Twojej usłudze? Czyli o skalowaniu aplikacji w Node.js - RST CodeMeeting

Editor's Notes

  • #3: Powtarza ten cytat mnóstwo ludzi, bez kontekstu. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. YouArentGonnaNeedIt(YAGNI)
  • #4: CMSy, frameworki,Własny pomysł na moduły, które przecież są niezależne, ale splątane ze sobą niczym supeł i nie ma mowy o wyciągnięciu ich poza folder z kodem Generalnie nie ma w tym podejściu nic złego - wszak to ważny element nauki Efekt Krugera-Dunninga
  • #31: COTE_ENV= Problem w AWS/chmurach, ale można rozwiązać za pomocą network layer w dockerze