Armağan Amcalar PRO
Armagan is the founder of Coyotiv GmbH, and is currently on a mission to bring a scalable and nimble engineering culture to startups and enterprises. Armagan is a public speaker, a mentor and a lecturer.
Armagan Amcalar
FullStack 2015, London
Oct 25th, 2015
Armagan Amcalar
Head of Software Engineering @ unu GmbH
Founder @ Lonca Works
dashersw
We love it.
We develop all kinds of software with it.
Programming model encourages stateful app design.
We love to daemonize it, all apps are running as daemons.
It doesn't scale well.
Works great as single process.
Works OK as a cluster.
What if you need more computing power?
How about horizontal scalability?
Because we have more problems
We're not just building express apps
Where's the flexibility and agility in that?
Be fast with your API response
Asynchronous processing (e.g., analytics)
You may need to scale very dynamically
High availability (fault tolerance)
IT WAS BTTF DAY A FEW DAYS AGO,
WHERE ARE MODULAR, COMPOSABLE DESIGN AND EVENTS?
Single code base
One process to rule them all
A bug anywhere crashes the whole system
May consume lots of stale resources
Hard to scale; needs even more stale resources
Request–response flow is one huge piece
Easy to manage
Separate 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
Request–response flow breakdown
Hard to manage
Communication between services
Transactional processes
Dynamic service configuration
Service discovery
Health checks & monitoring
Somewhat!
Use as service registry
Update config on any change in services
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
redis
d1
d4
d3
d2
publishes foo
notifies of foo
notifies of foo
notifies of foo
client request
session storage
logs
API
var redis = require('redis'),
client = redis.createClient(6379, '127.0.0.1');
client.publish('request', JSON.stringify({
body: 'some cool request'
}));
var redis = 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
A message broker for distributed applications
Like redis pubsub, with heavy focus on additional features
such as very flexible message routing
work queues, topics, fanouts, sinks, etc.
QoS management
round robin load balancing
message acks
rate limiting
unfriendly node.js library
var amqp = 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);
});
});
var amqp = 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) {
var body = msg.data.toString('utf-8');
console.log("received", body);
queue.shift(); // basic_ack equivalent
});
});
});
node.js framework for building fault-tolerant,
distributed applications
auto-discovery
mesh network, peer-to-peer communication
pubsub pattern
requester/responder pattern
client-side communication with websockets
load balancing with different strategies
daemon monitor
var Publisher = require('cote').Publisher,
publisher = new Publisher({
name: 'publisher',
broadcasts: ['update']
}),
workId = 0;
publisher.on('ready', function() {
setInterval(function() {
console.log('emitting', ++workId);
publisher.publish('update', workId);
}, 3000);
});
var Subscriber = require('cote').Subscriber,
subscriber = new Subscriber({
name: 'subscriber'
});
subscriber.on('update', function(message) {
console.log('update', message);
});
Payments processor service
Products catalog service
Purchasing service
User and accounts service
With RabbitMQ or cote.js we can;
Apply sophisticated programming paradigms
Scale nearly infinitely
Have fault-tolerant systems
Armagan Amcalar
armagan@amcalar.com
twitter: @dashersw
github: dashersw
blog: arm.ag
examples at https://github.com/dashersw/node-scale
e-commerce app case study:
https://github.com/dashersw/cote-workshop
By Armağan Amcalar
In this talk, Armagan explores different scaling strategies for Node.js applications like nginx and RabbitMQ, and observe their advantages and disadvantages. The last strategy will be a microservices solution via a Node.js framework, cote.js. You will learn how to implement an optimized, zero-conf, fault-tolerant, distributed scaling solution that plays extremely well with the microservices architecture.
Armagan is the founder of Coyotiv GmbH, and is currently on a mission to bring a scalable and nimble engineering culture to startups and enterprises. Armagan is a public speaker, a mentor and a lecturer.