Scaling microservices with Crossbar.io
Software Engineering Camp 2016, Tobias Oberstein, Alexander Gödde
http://goo.gl/vUUb5e
The what and why of Microservices
Taming Complexity
and avoiding
Taming Complexity: getting there
-
Divide & Conquer
-
One thing, one responsibility
-
Decoupling
Older techs:
-
CORBA
-
DCOM
-
SOAP/WSDL
-
All of above suck BIG time
-
We'll see why REST/HTTP isn't really an answer and why we use WAMP
Scaling Microservices using the Traveling Salesman Problem (TSP) as an example
TSP
TSP
TSP
TSP
11 cities: 39,916,800 combinations
30 cities: 2,652,528,598,121,910,586,363,084,800,000 combinations
One Algorithm: Simulated Annealing
Scaling the TSP
The problem: there are no 1THz cores (because physics)
Simulated Annealing is trivial to parallelize.
We could
-
use some tech specialized for parallelization of compute
-
use OpenMP to utilize all cores on single machine
-
use MPI to utilize all machines in a local cluster
or we could use Microservices
A TSP App
A TSP Microservices App
Microservice Interactions - Calls
Microservice Interactions - Distribute Information
So we need
-
Remote Procedure Calls (RPC)
-
Publish & Subscribe (PubSub)
Ideally in one protocol and using one tech.
Web Application Messaging Protocol (WAMP)
- WAMP (Web Application Messaging Protocol) fits that bill
- WAMP is a routed protocol, requires a WAMP router
- Crossbar.io is one WAMP router (ours)
-
open
-
13 languages
-
24 client, 12 router implementations (22/11 OSS)
Sessions
Sessions
var connection = new autobahn.Connection({
url: 'ws://127.0.0.1:9000/',
realm: 'realm1'
});
connection.onopen = function (session, details) {
console.log("connected");
};
connection.onclose = function(reason, details) {
console.log("connection closed/lost", reason, details)
}
connection.open();
Publish & Subscribe
Publish & Subscribe
Publish & Subscribe
Publish & Subscribe
Subscribe
function onhello(args) {
console.log("Got event:", args[0]);
}
session.subscribe('com.myapp.hello', onhello);
Publish
session.publish('com.myapp.hello', ['Hello, world!']);
Routed Remote Procedure Calls
Routed Remote Procedure Calls
Routed Remote Procedure Calls
Routed Remote Procedure Calls
Routed Remote Procedure Calls
Routed Remote Procedure Calls
Routed Remote Procedure Calls
Register
function add2(args) {
return args[0] + args[1];
}
session.register('com.myapp.add2', add2);
Call
session.call('com.myapp.add2', [2, 3]).then(
function (result) {
console.log("Got result:", result);
},
function (err) {
console.log("Error calling procedure", err);
}
);
Combining actions
- Call a procedure from an event handler
- Publish events from a registered procedure
- Dynamically subcribe/unsubscribe in a procedure
- Dynamically register/unregister in an event handler
- ...
Shared Registrations
Shared Registrations - Hot Standby
Shared Registrations - Hot Standby
Shared Registrations - Scale-Out
Shared Registrations - Scale-Out
Shared Registrations - Scale-Out
Shared Registrations
session.register('com.myapp.add2', add2, {
invoke: 'roundrobin'
});
Shared Registrations - Controlling Concurrency
Shared Registrations with Max Concurrency Limits
session.register('com.myapp.add2', add2, {
'invoke': 'roundrobin',
'concurrency': 4
});
The TSP App
The TSP App
The TSP App
Summary
-
Microservices: new answer, old problem
-
Connection patterns: RPC + PubSub
-
Crossbar.io + Autobahn make this easy
-
Scaling and hot standby are offered by the router