ZERO-CONFIGURATION
MICROSERVICES

WITH NODE.JS AND DOCKER

Armagan Amcalar

FullStack 2017
July 13th, 2017

Before we start...

Things you may want to install:

Who am I?

Armagan Amcalar
Head of Software Engineering @ unu GmbH
Founder @ Lonca Works

        dashersw            dashersw

AUTHORED ON GITHUB

Outline

Microservices overview

An example e-commerce application

Properties of a modern microservices approach

Brief intro to a Node.js microservice

How Docker helps

The real deal

dashersw

What is not a microservice?

Async operations with queue (and other) systems

Having 50 different queue consumers (for notifications, logging, reconciliation services, e-mailing etc) doesn’t mean you have 50 microservices

 

Multiple programs running on a single machine and communicating over HTTP

dashersw

What is a Microservice?

dashersw

If you are breaking down the fulfillment of a client request into multiple collaborating services that run in their own memory space, then you are doing microservices.

 

THE BASELINE

Microservices

The quality of your approach depends on how well you apply Domain Driven Design and other best practices.

 

You have to —

Embrace change

Give autonomy to teams, to services

Automate testing, configuration, deployment, monitoring and more

Favor cattle over pets

dashersw

An example e-commerce app

dashersw

Auto-discovery

dashersw

Auto-discovery

dashersw

Zero-configuration

dashersw

Highly-redundant

dashersw

Fault-tolerant

dashersw

Self-healing

dashersw

An example in Node.js

const cote = require('cote'),
    models = require('./models');

const userResponder = new cote.Responder({ name: 'user responder' });

userResponder.on('list', req => models.User.find(req.query));
userResponder.on('get', req => models.User.get(req.id));
userResponder.on('create', req => models.User.create(req.user));
const cote = require('cote'),
    router = express.Router();

const userRequester = new cote.Requester({ name: 'user requester' });

router.get('/users/:id', (req, res, next) => {
    userRequester.send({type: 'get', id: req.params.id})
        .then(user => res.send(user))
        .catch(next);
});

router.get('/users', (req, res, next) => {
    userRequester.send({type: 'list'})
        .then(users => res.send(users))
        .catch(next);
});

module.exports = router;
  • Zero dependency: Microservices with only Node.js
  • Zero-configuration: no IP addresses, ports or routing to manage
  • Decentralized: No fixed parts, no "manager" nodes, no single point of failure
  • Auto-discovery: Discovery without a central bookkeeper
  • Fault-tolerant: Don't lose any requests when a service is down
  • Scalable: Horizontally scale to any number of machines
  • Performant: Process thousands of messages per second
  • Humanized API: Simple to get started with a reasonable API

dashersw

How does Docker help?

Immutable environment
Overlay network
Auto-restart on failure
Docker Swarm — orchestration capabilities, scaling, rollbacks, secrets management, highly-available

dashersw

Let's dive deep & build some microservices!

 

By the way, here's the demo for the previous example:

http://admin.cotejs.org

http://end-user.cotejs.org

http://monitoring.cotejs.org

 

Source code & Docker configuration available at

https://github.com/dashersw/cote-workshop

dashersw

thank you!

Join cote.js community

Let's keep in touch!

Armagan Amcalar
  dashersw

slides: tr.im/fs2017
demo: tr.im/dcmd

Zero-configuration Microservices with Node.js and Docker

By Armağan Amcalar

Zero-configuration Microservices with Node.js and Docker

Microservices are taking the world by storm but it implies more than what is currently marketed. This talk details how a proper microservices architecture should work: zero-configuration, highly-redundant, fault-tolerant, self-healing mechanism with auto-discovery. Such an implementation with Docker and Node.js is shown, where the principles are applicable to any modern language.

  • 3,544