Upload
john-head
View
227
Download
0
Embed Size (px)
Citation preview
8/10/2019 Scale Node
1/30
SCALING NODE.JSAPPLICATIONS WITH
REDIS, RABBITMQ & COTE.JS
Armagan AmcalarJSIST 2014, Istanbul
Sep 27th, 2014
8/10/2019 Scale Node
2/30
WHO AM I?
Armagan AmcalarCo-founder, Chief Software Architect
dashersw
Startup Kitchen
AUTHORED ON GITHUB
pedalboard.js
tartJS
geneJS
cote
semaver
jira-bot
HOBBY PROJECTS
pedals.io
trax.io
8/10/2019 Scale Node
3/30
NODE.JS
We love it.
We develop all kinds of software with it.
We love to daemonize it.
8/10/2019 Scale Node
4/30
THE PROBLEMIt doesn't scale well.
Programming model encourages stateful app design
Works great as single process
Works OK as a cluster
8/10/2019 Scale Node
5/30
WHAT'S NEXT?What if you need more computing power?
How about horizontal scalability?
8/10/2019 Scale Node
6/30
CURRENT SOLUTION
NGINX
NODE-HTTP-PROXY
REVERSE PROXY
8/10/2019 Scale Node
7/30
NGINXEasy to set up if you're familiar
with nginx
Hard to maintain
Yet another technology
dependency
NODE-HTTP-PROXYHard to set up even if you're
familiar
Hard to maintain
Very low level
8/10/2019 Scale Node
8/30
WE NEED A DIFFERENT SOLUTION.Because we have more problems
We're not just building express apps
We were programming the DOM, we need that flexibility
8/10/2019 Scale Node
9/30
MORE PROBLEMS?Be fast with your API response
Asynchronous processing (e.g., analytics)You may need to scale very dynamically
Fault tolerance
THE YEAR'S 2014, WHERE ARE THE EVENTS?
8/10/2019 Scale Node
10/30
8/10/2019 Scale Node
11/30
8/10/2019 Scale Node
12/30
MICROSERVICESSeparate code base
Multi processes for each service
A bug in a service crashes only that service
Consumes minimal resources
Scales well, needs minimal additional resources
Supports event-driven architecture
Requestresponse flow breakdown
Hard to manage
8/10/2019 Scale Node
13/30
EVENT-DRIVEN ARCHITECTURE
PUB-SUB PATTERNOBSERVER PATTERN
8/10/2019 Scale Node
14/30
PUB-SUB PATTERN
Just like DOM events, what we're used to build.
Instead of click events, you have custom events (e.g. in jQuery)
Instead of DOM element interaction, you have daemon
interaction
8/10/2019 Scale Node
15/30
OBSERVER PATTERNFirst-of-its-kind event driven pattern
You an object property, not an arbitrary event
Like all your click handlers have to have the same name
Limits possibilities
8/10/2019 Scale Node
16/30
ENTER REDIS
Originally a NoSQL database
Key-value pair server with lots of great features like sets, etc.
Pub-sub capability
Supports events based on channels and patterns
Very cool node.js library
8/10/2019 Scale Node
17/30
A REDIS PUBSUB-BASED ARCHITECTURE
redisd1
d4
d3
d2
publishes foo
notifies of foo
notifies of foo
notifies of foo
client request
session storage
logs
API
8/10/2019 Scale Node
18/30
EXAMPLE
varredis = require('redis'),
client = redis.createClient(6379, '127.0.0.1');
client.publish('request', JSON.stringify({
body: 'some cool request'
}));
varredis = require('redis'),
logger = redis.createClient(6379, '127.0.0.1');
logger.subscribe('request');
logger.on('message', function(channel, message) { if(channel == 'request')
console.log(JSON.parse(message));
});
Client
Logger
8/10/2019 Scale Node
19/30
QUICK DEMO
8/10/2019 Scale Node
20/30
ENTER RABBITMQA message broker for distributed applications
Like redis pubsub, with heavy focus on additional features
such as flexible message routing
work queues, topics, etc.QoS management
round robin load balancing
message acks
rate limiting
unfriendly node.js library
8/10/2019 Scale Node
21/30
WORK QUEUES
REMOTE PROCEDURE CALLS
8/10/2019 Scale Node
22/30
EXAMPLE WORK QUEUEvaramqp = require('amqp'),
connection = amqp.createConnection(),
workId = 0;
connection.on('ready', function() {
connection.queue('work_queue', {autoDelete: false, durable: true}, function(queue) {
setInterval(function() {
connection.publish('work_queue', 'message #'+ ++workId, { deliveryMode: 2});
console.log('sent message #'+ workId);
}, 1000);
});
});
varamqp = require('amqp'),
connection = amqp.createConnection();
connection.on('ready', function() {
connection.queue('work_queue', {autoDelete: false, durable: true}, function(queue) {
queue.subscribe({ack: true, prefetchCount: 1}, function(msg) {
varbody = msg.data.toString('utf-8');
console.log("received", body);
queue.shift(); // basic_ack equivalent
});
});
});
8/10/2019 Scale Node
23/30
QUICK DEMO
8/10/2019 Scale Node
24/30
ENTER COTE.JSnode.js framework for fault tolerant, distributed apps
developed at Startup Kitchenpartially funded by TUBITAK
8/10/2019 Scale Node
25/30
COTE.JS FEATURES
auto-discovery
mesh network, peer-to-peer communication
pubsub pattern
requester/responder patternclient-side communication with websockets
load balancing with different strategies
daemon monitor
8/10/2019 Scale Node
26/30
EXAMPLE ARCHITECTURE
8/10/2019 Scale Node
27/30
EXAMPLE PUB-SUB IMPLEMENTATIONvarPublisher = require('cote').Publisher,
publisher = newPublisher({
name: 'publisher',
broadcasts: ['update']
}),
workId = 0;
publisher.on('ready', function() {
setInterval(function() {
console.log('emitting', ++workId);
publisher.publish('update', workId);
}, 3000);});
varSubscriber = require('cote').Subscriber,
subscriber = newSubscriber({
name: 'subscriber'
});
subscriber.on('update', function(message) {
console.log('update', message);
});
8/10/2019 Scale Node
28/30
QUICK DEMO
8/10/2019 Scale Node
29/30
CONCLUSION
With Redis, RabbitMQ or cote.js we can;
Apply sophisticated programming paradigmsScale nearly infinitely
Have fault-tolerant systems
8/10/2019 Scale Node
30/30
THANK YOU!
CONTRIBUTE TO COTE.JS
github.com/dashersw/cote
LET'S KEEP IN TOUCH!
Armagan Amcalar
twitter:github:
blog:
@aamcalardashersw
arm.ag
examples at https://github.com/dashersw/node-scale