Monolithic vs. Microservices Architecture: Which is Right for Your App
Posted: Feb 07, 2019
Two major types of software architecture are monolithic and microservices. The last one has become extremely popular in recent years. While monoliths are still there and programmers work with them as well. That is why the question "monolithic vs. microservices architecture" is still actual when we talk about app development.
What is a Monolithic Architecture? A monolithic architecture is a model of software structure which is created as one piece where all Rails tools (ActionMailer, ActiveJob, ActionCable, etc.) can be gathered together with the code that these tools applies. The tools are not connected with each other but they are also not autonomous.
If one feature needs changes, it will influence the work of the whole process and other features because they are parts of one process.
Let’s recall what Ruby on Rails is, what it can offer, its pros and cons. Its most important benefit is that it is easy to work with.
If you write 'rails new' you immediately get a new application at once, then you can create any REST API you want and use Rails helpers and generators, which makes development even easier.
If you need to send emails in your Rails app, then use Rails ActionMailer. When you need to do some hard processing, ActiveJob will help you. With Rails 5 you will also be able to use websockets out of the box. Thus, it will be easy to create chats or make your application more interactive.
In case you use correct DSL syntax, you can use all that and even more immediately. Moreover, you don’t have to know everything about the internal implementation of these tools, consider it’s DSL, and receive the expected result.
What is a Microservices Architecture?
Microservices appeared as an alternative to monoliths in order to solve all issues and bottlenecks caused by the limitations of the monolithic architecture. These are standalone processes which serve certain purposes but they have far less responsibilities comparing to common Rails apps. Ideally they have to serve only one purpose according to the SRP.
Let’s consider an example. As you know, our brain consists of two hemispheres. The left one is responsible for rational and logical things while the right hemisphere performs functions that are connected with creativity. They don’t delegate their tasks to each other but they have some communication channels. Moreover, they work concurrently and that’s exactly what we want.
Microservices Example: Practical Use
We cannot get down to practice and code at once because the question of building microservices also touches upon the matter of architecture and interaction between the microservice and the main app. These points are more important than the code of your microservice. Don’t forget that it is different from what you get with Rails out of the box.
Now your application consists of the main app, microservice, and communication between them. Chances are that it will work for one or two requests locally but will not work in production, so you should treat it more judiciously than just the code of your microservice and everything that is in between.
Design Microservices Architecture and Communication Between the Main App and the Microservice
1. Prefer to use simplex communication between the main app and the microservice. Otherwise you may have issues with synchronization when some of your components in this pipeline have performance issues or are not available for request.
correct way: Main App? microservice? 3rd Party APIwrong way: Main App? microservice? 3rd Party API
2. It’s better to build communication between a microservice and the main app using the publish/subscribe pattern, not the observer pattern. Apart from hexagonality, it also can bring concurrency.
This is appropriate if there are more than one microservice in our architecture and they are do not require sequential processing. Moreover, if you use direct communication between the main app and the microservice, the microservice will be available at some port. You will have to foresee its unavailability for the outside world (today is 2108 and we have Kubernetes, Docker, an others that will help us do it but we should still be careful).
If you choose communication via pub/sub (Message Bus), you should invoke your microservice as a daemon process and the issue mentioned above will be solved itself.
Imagine that we have the main app that performs a required function, pushes data to a message bus and all of its listeners get it immediately. Websockets microservice, Mailer microservice, SMS microservice and other assumed microservices receive this data co-instantaneously and process it concurrently. This seems to be a more effective solution than direct communication between them, doesn’t it?
Learn more here. This article will help you to choose the right architecture for your application.