DEV Community

Cover image for Get a Taste of Microservices Architecture and Communication
Deepak Ahuja πŸ‘¨β€πŸ’»
Deepak Ahuja πŸ‘¨β€πŸ’»

Posted on • Edited on

Get a Taste of Microservices Architecture and Communication

Building applications in Monolithic architecture includes a client making request, server (with router, authorization middle-ware, some set of features, business logic) and a database. The whole App can be put into place using these. The build artifact is a single executable hosted on a single VM with consistent a technology stack.

In a Micro service, this set makes only a single feature for the app. They work independent of each other without any direct dependency on each other's database. If any of the service is down, the app still works. The services are small, autonomous, and independently deploy-able.

Monolithic Vs Microservice Arcitecture

Monolithic vs Micorservices architecture

Monolithic can work well for small applications but even a single line code change means downtime, and it cannot be easily scaled horizontally (add new services) and can only be scaled vertically (means more processing power).

Benefits of Microservices

  1. Small Services It can be owned by a team, easier to understand and rewrite.
  2. Technology Choice Adopt new technology, use right tool, Standardize where it makes sense.
  3. Individual Deployment It has Lower risk of app failure, no downtime, frequent updates
  4. Scaling It can scale services easily, cost effective

Why do all the hard work to create many different code bases and use heterogeneous technologies to create an app?

There are many challenges in micro services too, for example the communication with each other. The interactions are complex if not avoided can be inefficient due to web of requests b/w services.
In micro services we follow two rules strictly:

  1. Each service gets it's own database (if it needs one) This is called Database-Per-Service pattern, we do it because if we use only single, and that db is down, the whole app comes down, the Single Point of Failure needs to be avoided, and secondly is scalability, it is a lot easier to increase capacity and throughput of databases as per needs of each service.
  2. Services will never, ever reach into another services database If anything ever goes wrong with database of dependent service, other service also gets lost, secondly, If schema of one database is altered, both service would need to be updated. we can also use different types of databases best suited for specific needs.

Let's try to visualize how would it work and find solutions to raised challenges,
Here's an example of the app with these 3 features:

  1. Users can sign up
  2. User can submit posts
  3. User can comment on each post basic app example

But now if we want to add another code that can list comments for post of a particular user:

  1. we need user from users collection
  2. we need to find posts of that user
  3. we need to fetch comments of that post

In monolithic server we can reach out to each database and fetch required information. Here's how it would look:
Monolithic server
But this pattern is very inefficient, we'll see in a while.
By going by Database-Per-Service pattern in Micro services, We can add another service that can do this work for us:

Service D

How will it reach out to three separate databases of different services? This is not allowed in Database-Per-Service pattern. To figure this out we will understand how to establish communication between services.

There are two general strategies to establish a communication strategy between services:

  1. Synchronous Communication Services communicate with each other using direct requests
  2. Asynchronous Communication Services communicate with each other using events

Note: These are not as same JavaScript's definition of these terms.

Example of Sync Communication:

Sync Communication

One service can communicate with another service using a direct request, this may not need to be HTTP, it could be any type of request. In our case to request comments of a post of a user, The service D will make 3 different requests to each of other service.

Advantages:

  1. Easy to reason about and add new service straightforward
  2. New services don't need a database

Disadvantages:

  1. The entire request is only as fast as it's slowest request. For eg: if request 1 takes 10ms, request 2 takes 10ms but request 3 takes 100ms, the response would time would be more than 100ms
  2. Makes service dependent on each other, if any service goes down, the entire service goes down
  3. Difficult to track requests due to multiple nested requests.

Example of Async Communication:

This type of communication would need an Event Bus which can emit and receive events, that will be connected to every service in the application.

This decouples the services from each other. Instead of one-on-one communication, they talk to each other using a message broker. If other service is down, the first service can still work and second one presume itself later. There are two types of messages: Commands ("Do this please") and Events ("Something happened in Past").

Asynchronous Communication

Now in our case service D would first broadcast an Event (UserQuery) to every other service, those services will handle the event if they want and can again release event for result for that Event. From that User received, Service D will again send a PostsQuery, and then finally from those Posts, another event CommentsQuery to Event Bus. Now Event Bus will broadcast each event to every service until service D will receive the result.

This approach is very bad and has all the downsides of synchronous communication as well it many of it's own.

A better approach would be to add a database that can serve the required information. Other services will emit events and populate this database, now this database will be ready to serve the request instantaneously.

Async communication

Advantages:

  1. Service D has zero dependency
  2. The queries are very fast

Disadvantages:

  1. Hard to understand and code
  2. Data Duplication
  3. Extra Storage cost (but cheap!)

Thanks for making it to the end of the post, you are awesome!
You just took the first step in seeing the application architecture from a high level perspective. There are tons of information out there to learn more on this. Don't forget to leave your thoughts. I got this information from this awesome Stephen Grider's course, Here's the non-affiliate link (https://www.udemy.com/share/102VKE/).
Please share it if you found it helpful or drop me a hello on twitter :)

-- Edit
Follow up read -

Top comments (7)

Collapse
 
siy profile image
Sergiy Yevtushenko

Microservices and monoliths are not architectures, they are packaging options. And almost nobody mentions that once you switch to microservices, you stepping into area of distributed applications, which is far more complex than usually described in posts like above. So it's usually better to don't do microservices if you can.

Collapse
 
dpkahuja profile image
Deepak Ahuja πŸ‘¨β€πŸ’»

Hey, Thanks for reading.
Yes, but simply there are no one size fits all here. Something like netflix with 1Ks of services are running well as well as my hobby project on a single code base. Depends on Developer resources, cost, requirement and ROI. Though i would read more into it before agreeing to the package options context. I think you are confusing a mono repo with monolithic system. Not sure.
Anyways, Thanks again for reading to full.

Collapse
 
siy profile image
Sergiy Yevtushenko

I'm definitely not confusing mono repo with monolith. Moreover, I'm designing and implementing distributed systems far longer than term "microservices" exists.

References to Netflix and other successful applications of microservices are heavily misleading. They make people feel that microservices are easy to implement and use in production. Everybody focusing at "1K microservices" and miss equally important thing: infrastructure behind these "1K microservices". The whole idea of microservices is based on moving huge part of internal complexity to infrastructure. Unfortunately many (I'd say most) organizations don't have adequate infrastructure. Switching to microservices for such organizations means that they need to build two things in parallel - the system and the infrastructure.

Thread Thread
 
dpkahuja profile image
Deepak Ahuja πŸ‘¨β€πŸ’» • Edited

Hey, Thanks for the insight. It's very useful.
I still have a long way to go before i can add more value to this discussion. Needs more experience, but i really liked the building two parallel things point. Thanks, Anyways i added link to one your articles as a follow up read :)

Collapse
 
brunner1000 profile image
Brunner

A very good post.
I think, to use microservices or not, will depend on the product and its specific requirements.
I can compare microservice architecture and monolithic architecture to data structures and algorithms.
There is a better algorithm for every code problem. But most newbie developers do not spend enough time learning to choose the right algorithms for their project. This is because, the current speed of computer memory and processor enables even the slowest algorithm to complete its task within a reasonable amount of time.
But this does not mean that it is good to ignore the right DS and Algorithms. And I also think that microservices could be the best architecture for most products out there. Especially ones that have a large user base and span more than one continent

Collapse
 
dpkahuja profile image
Deepak Ahuja πŸ‘¨β€πŸ’»

Hey, Thanks for reading the whole post.
I agree, Sometimes it may be an overkill to go over these complexities. but i have prepared a coded application example which i may post sometime soon, in which it explains how it is different to add new services, I do have commented on Scaling (horizontal and vertical).
I loved how you explained the computer being too fast to find difference b/w algorithms. This is a unique comment.

Collapse
 
brunner1000 profile image
Brunner

thanks for your positive comment.
Looking forward to your code application example