From Monolith to Microservices

#nodejsarm

Varik Matevosyan

Steadfast.tech/CTO

varik@steadfast.tech

github.com/var77

linkedin.com/in/varik-matevosyan-99200a108/

Overview

  • What is a monolithic application
  • Moving to microservices
  • Monolith vs microservices
  • My experience with microservices

What is a monolithic application

When talking about monolithic application consider it as a big monster application in which all the services are included, and there is single shared source of data

Problems with monolithic applications

  • Inefficient scalability
  • Service crash === application crash
  • Project maintenance

When talking about monolithic applications some people think that they are not scalable, but that's not true you can easily scale the monolith application horizontally, but when talking about the efficiency it can take a lot more resources than scaling the application with microservice architecture.

Inefficient scalibility

Consider the following scenario, you have a monolithic chat application, and you notice that the socket part is in a high load, so you should scale your application, but you can not scale just the socket part you should scale the whole monolith.

Inefficient scalibility

Socket

API

UI

DB

Socket

API

UI

DB

Now consider the following you have made change in your application's UI renderer and now should update it, so you should restart the whole application, which means you'll have downtime in your socket connections. Or if there would be some bug in you API the UI and Socket will be also crashed because of that.

Server downtime

Socket

API

UI

DB

Despite the quick start up of monolithic applications it's pretty hard to maintain the project as it gets bigger, and it's twice harder for new developers, it's like a big spaghetti code which can be broken easily if you do something wrong by mistake.

Project flexibility and maintenance

Moving to Microservices

"Do you have time to do it twice?"

"We don't have time to do it right!"

Moving to Microservices

Let's split our monolithic application into Microservices, for that firstly we should combine functions that have similar functionality and then wrap them into a single microservice, we should also consider about splitting our database, but we'll talk about it a bit later

But before we start, let's talk about some Nodejs frameworks and libraries designed for microservices and what should they provide us.

What we should expect from the good microservice library

  • Transport for service to service communication (HTTP, TCP)
  • Service registry to dynamically register a new service
  • Service discovery to discover new registered services automatically
  • Load balancing between services

Now we can start splitting our monolith, for the first we can split Socket, API and UI parts to separate services, so our application will look something like this.

Socket

API

UI

DB

API

Socket

UI

DB

For efficient microservice architecture our microservices should satisfy to some requirements

  • Each service should have it's own data store and state
  • Services should be independent, isolated and loosely coupled
  • Access to service's state should be only external via the API provided by the service

Now it's better than monolith, but it's far from the good microservice architecture

  • Services should be small and responsive for exactly one thing or be meaningful

Let's look what is wrong in our example, and what can we do to make it better.

API

Socket

UI

DB

Here we have Socket service which can be also split into parts for example, pure chat service which will send messages between users, flood/spam checker service, link/markdown parser service, etc... 

Messaging

Spam

Parser

API

UI

DB

Now we can consider to be done with the socket service, but there's also one thing left here the data, so we can take our messages collection out from our database and move it to a separate one

Messaging

Spam

Parser

DB

messages

DB

API

UI

We are now done with our socket service, and now we have 3 separate microservices which can be used not only in this project, but internally. Now let's move on and refactor our API service

Messaging

Spam

Parser

DB

messages

DB

Auth ( + social auth)

Payment

 

(sticker packs etc..)

User management

DB

users

DB

orders

Proxy

We've finished splitting our API service and we got 3 separate microservices and we get rid of the single database, so now each service has it's own data store. We also added a proxy layer to proxy front-end calls to our microservices, to use a single endpoint in the client side. Now let's compare our monolith and microservice architectures

Socket

API

UI

DB

Monolithic Architecture

UI

Microservice Architecture

Messaging

Spam

Parser

DB

messages

Auth ( + social auth)

Payment

 

(sticker packs etc..)

User management

DB

users

DB

orders

Proxy

UI

For the first it can be more messy and complicated, but it solves a lot of problems and speed up development for big projects and big teams, now let's look how we could solve the same scaling problem in this architecture

Messaging

Spam

Parser

DB

messages

Auth ( + social auth)

Payment

 

(sticker packs etc..)

User management

DB

users

DB

orders

Proxy

Messaging

As we can see, we just run one more messaging microservice and do not scale the whole application, and as I told you before service registry, discovery and balancing should be handled from our microservice framework or library. With the same approach now if we would like to change something in our parser service, then we can only restart that microservice and our changes will be live without affecting other services.

Monolith VS Microservices

Now let's compare this two architectures and see both advantages and disadvantages. 

It's not necessary to use the microservices  for each project, it depends on the needs and sizes of team/project, there can be cases where using monolithic architecture would be better than microservices.

So what are the advantages of using microservices

  • Independent and reusable services

    for example if we build another application which will have a chat, we can easily integrate our messaging, parser, spam/flood checker, microservices there.

  • Easy unit and integration testing
  • Independent scalability

                              we can scale our application partially saving resources.

  • Parallel and fast development

                                                               It's incredibly fast to develop with microservices with a team, as they the microservices are                                                                independent they can be developed parallel and the language do not matter, they just                                                                       should give an API interface and work with I/O scheme

  • New developers can get into the project more easily

           It's the same as trying to understand a big function with lots of conditions and a function which is                                  separated into smaller functions.

Disadvantages of microservices

  • Slow startup

    compared to monolith application the project set up can be more slow, because in monolith it's just all in one place so you can not think about service to service communication, splitting databases, what microservices you should have, etc..

  • Devops and building into production

    it could be more difficult to do the devops part of microservice application, service management, debugging and log management can be more difficult than in monolith application.

  • End to end testing

    writing ent-to-end tests for application can be pretty hard, because you should connect all the microservices together to be able to make the test

  • Database joins

    it's hard to do database joins with microservices, but there are some techniques to do it.

My experience with microservices

In our company (Steadfast) we are using microservices a lot, and we use our libraries and frameworks to manage them (zeronode, kitoo-core, wirentity)

My experience with microservices

We are mainly doing game projects, and we use microservices to separate logic parts for games, and to split API into several parts.

My experience with microservices

So in our last project which was a board game, we were using microservice architecture, with kitoo-core to connect services each other. It's pretty easy and handful to do microservices with kitoo-core because you just define your request handlers, and give a name to your service, after that you just need to run one or multiple instances of kitoo-core routers and connect your service to them, then service registry, discovery and load balancing is done automatically for you. 

My experience with microservices

So by using it we managed to give an MVP in about 2 weeks via doing parallel development. We make about 12 microservices and cover each microservice with about ~90% unit tests. There the microservices were mostly stateless so our data model did not matter for request/response pattern to match with database model.

My experience with microservices

For API we had 4 microservices which were shipped with their clients. It's always a good habit to make a client for you microservice so there will be all available interface of your microservice. And for process management we are using pm2 which is a great tool for managing NodeJS applications.

Thank you!

Don't hesitate move to microservices!

From Monolith To Microservices

By Varik Matevosyan

From Monolith To Microservices

  • 154