You may have heard about microservices, about their advantages and disadvantages. I tried to gather all the possible information in order to create a comprehensive documentation on microservices. This guide will act as a helping hand for those who want to know this in details.
ARN – Amazon resource name
AWS – Amazon Web Services
AWS CodeBuild – CI service that compiles source code, runs tests, and produces software packages
AWS CodeDeploy- service that automates software deployments to a variety of services such as Amazon AWS Fargate, AWS Lambda, etc.
AWS CodePipeline – CD service that automates your software release process
AWS Fargate – Engine for Amazon ECS that allows you to run containers as serverless nodes
AWS Lambda – Amazon function which is used as a separate serverless service
Amazon Aurora – Serverless MySQL and PostgreSQL relational database built for the cloud
Amazon Cloudwatch – Monitoring and management service, can be used for logging and producing events
Amazon DynamoDB – Serverless key-value and document database that delivers single-digit millisecond performance
Amazon S3 – Simple Storage Service
Amazon SAM – Serverless Application Model
Amazon SNS – Simple Notification Service
Amazon SQS – Simple Queue Service
Amazon X-Ray – Referrers to a service allowing to x-ray all your amazon architecture
CORS – Cross-Origin Resource Sharing
DDD – Domain-driven design
DI – Dependency injection
Docker – Operating-system-level virtualization to develop and deliver software in packages called containers
EDA – Event driven architecture
JWT – JSON web token
LSP – Liskov substitution principle
NVM – Node version manager
SoC – Separation of concerns design principle
With every product, there comes a phase when adding a new feature to the existing code base becomes so hard that the cost of implementing the new functionality exceeds all its benefits. Undoubtedly, good and attentive solutions architects can help in advancing and guiding the development in the right direction. Moreover, the evolution of technologies has changed the way we build the architecture of applications. The most popular approach at the moment involves cutting one large piece of code into many small projects, where each is responsible for their specific job. But before designing such systems it is necessary to understand the differences between monolithic and microservice architecture, discuss what type of architecture should be used by teams for which projects, and explore their advantages and disadvantages. It is essential to have a solid understanding of what we are building and which purpose, so that future changes do not require rewriting everything to hell. This document will describe:
- what are microservices
- crucial benefits and drawbacks of using microservices architecture as opposed to monolith approach
- Serverless architecture
- key serverless services which can be utilized in designing the system
- the key differences between RDBMS and NoSQL databases
- go through authentication mechanisms and disclose the microservices/serverless automation deployment process
- provides guidance for developers about how to design micro service architecture when to use AWS Lambdas, Docker containers, NoSQL databases, etc.
Microservices – what is it about?
There is more than one definition, however it can be described using a good variety of requirements for the system, according to which it could be attributed to the microservice architecture. The system can be called microservice if microservice works only with a granular module, as limited as possible area and it performs the minimum number of functions to achieve a specific goal. Moreover, in the theory of microservices it is often often assumed that microservices must be completely independent and communicate with other services remotely over the network using REST, event bus , message broker software or some other RPC protocol (event buses and message brokers are the most preferable since microservices should not know about each other). Microservices architecture allows big application to divide into small, loosely coupled services. On the image below an example of a possible implementation of the platform is presented.
As it can be seen the obvious difference between these two designs is that the left one is implemented in a form of a single large block – monolith, whereby the right is presented as a more complex structure of small specific services where each service has its own specific role. By looking at this scheme at this level of detail, it is easy to see its attractiveness.The following visible advantages can be distinguished:
- Tiny independent components can be created by small independent teams. The group can work on changes in the one service without affecting another service or even knowing about it. Furthermore, the amount of time required to learn the way component works, is significantly reduced, therefore it becomes easier to develop new functions.
- The fact that each component can be deployed independently, allows you to release new features quickly and with less risk. Fixes or features for one component can be deployed without the need to redeploy other parts of the system.
- Independent scalability of the components provides an ability to scale highly loaded components without the need to scale other moderately used ones. It makes scaling flexible and helps to reduce costs associated with the scaling.
- Because components are dedicated for a specific responsibility, it makes it easier to reuse them in other services.
Taking into account all the points presented above by looking at it from a high level perspective, the advantages of the microservice model over the monolithic seem obvious. Albeit, if it is tremendously advantageous, then why it is not used across the board and why it was not brought into development before? In order to answer this question we have to remember that it was actually in use for a pretty long period of time. There were a variety of patterns, tools and principles which can be considered as prototypes and components of microservices. It can be stated that microservices emerged from service-oriented architecture employing its inalienable tools such as bounded context pattern and enterprise service bus as a communication system.
The reason for its wide popularity is just because recent technological improvements have allowed us to reach a new level in this approach and make the development of distributed computing architecture smoother and sustainable. However, we know that every big benefit has its own shade where all drawbacks are hidden.
- Extremely high architectural complexity which includes developers and operational complexity. Developers will need to have all services whey have to deal with to be run on their workstations which can partially be resolved by proper containers set up and different tools, but the problem will still stay relevant. Moreover, the entry threshold into the whole system for developers will be grown dramatically. On the other side people who are dealing with supporting existing services will need to maintain tens, hundreds, or thousands of different services. Even that can be partially resolved by truly adopting DevOps practice by all engineers. Although, the problem with that is that many companies do still have separate operational and development departments (our company is not an exception in this area).
- Without a serious competence, the process can become detrimental for the company. In order to understand more clearly, just think about an organization where everything is not ideal with the work even of a single monolithic system. Why, with an increase in the number of systems, which complicates the operation, testing and development the situation will become better? However, it is necessary to say that results can be great if the work was done by experts.
- Dependencies between services can tear apart the whole architecture. In other words, there is a huge gap between theory and practice. It can be illustrated by the fact that all resources describing the benefits of microservices, do it using small independent components. Unfortunately, in practice the components are not independent. Usually when you get to the bottom of all the details, it is easy to find that everything is much more sophisticated than in the intended model. This is where everything becomes very complex. It can easily happen that even in the case of the theoretical possibility of an isolated deployment of services you will end up doing deployments of components with mutual dependencies as a group. Thereby, you will need to maintain consistent versions of services that have been tested in the integration. This problem can partially be leveled by using blue green deployments but it if you do not have a properly configured automation deployment process then it can be detrimental issue.
There are other problems associated with the use of microservice approach in the system design. Many of them are no less severe than the previous ones. Among the problems, it can also be highlighted the problems associated with the control and isolation of connections, problems of synchronization and control of data integrity between different nodes of the system due to partitioning of data, testing of microservices, etc.
It can be concluded that microservices can be used if you:
- company does not have a tight deadline because development of the project using microservices, requires a solid architecture planning to ensure it works and how it will be functioning;
- have a large team of developers (if all your team can sit at one table, perhaps monolith is a better choice for you and the entire architecture of your product should be reviewed rather than constructing a solution using a complex architecture);
- team have knowledge of different languages;
- company has a good reason for worrying a lot about the scalability and reliability of your product (however the reliability can be achieved even using monolith);
- already have the monolith app which has performance problems with its modules.
All the above points can be schematically be presented on below flow diagram.
Ultimately, it can be presented on the diagram below which shows that during the system development there is a moment when the price of microservices pays off by reducing the costs of a decrease in the productivity of the team when the system becomes more complex. Moreover, it shows that smaller projects wirth the medium complexity, can have more advantages of using the monolithic approach.
Nevertheless, some of the problems associated with the microservices can be mitigated which makes benefits are more bright and drawbacks are less painful. By architecturing your entire platform or at least areas for which microservices are supposed to be created and distributed, to be stateless, the development process can be improved, deployments simplified and overhead reduced.
to be continued