What is a microservices architecture and is it the right choice for your next app?

An introduction to the microservices architectural approach: advantages, mistakes to avoid and the approach's role in future-proofed software and web development

BlogUPDATED ON March 17, 2022

Microservices

In this blog of DevOps consulting series, we look at what microservices architecture is and how the structural style allows for:

  • Easier and faster to build and maintain large, complex software systems.
  • Greater availability.
  • The flexibility to code different chunks of the code that make up an app in different languages and frameworks.
  • Autonomous cross-functional teams can efficiently contribute to a single large software development process.

We’ll also look at potential mistakes that can be made with a microservices approach and when it may not be the right choice for an application.

Agile & DevOps teams and consultants

Supercharge your next cloud development project!

What is a microservices architecture in software development?

The term ‘microservices’ refers to a service-oriented structural style to software architecture that splits an application into a collection of loosely-coupled services. Derek Comartin describes microservices as:

“Loosely coupled service-oriented architecture with bounded contexts.”

And Bounded Context, a term from Domain-Driven Design, is defined as:

“If you have to know too much about surrounding services you don’t have a bounded context.”

Microservices involve logically separating pieces of code in a way that they can run independently with as few dependencies on each other as possible. But individual microservices are still able to “talk” to each other and work together to form a complex application from the sum of its microservices.

Separating out chunks of code into self-sufficient microservices means minimising dependencies and the need to coordinate changes being made in one service with others. It also means one service failing will have less of an impact on the functioning of the application as a whole.

Before the rise of microservices, developers tasked with the implementation of support for third-party services via API and various clients tended to use monolithic architecture patterns. It was the most obvious way to implement such applications and helped utilize hardware resources more efficiently.

Fast forward to 2022, and microservices, which support the CI/CD priority of a DevOps approach to web development, are now the preferred approach.

Microservices in the context of Containers, Docker, Kubernetes and Serverless

Microservices are often discussed within the context of Containers, Docker, Kubernetes and Serverless architecture. However, it should be clarified that these are all tools and technologies used by backend architects used to physically deploy microservices. Microservices refer to the logical separation of chunks of code into autonomous services. Containers, Docker, Kubernetes and Serverless architecture are tools and approaches to the physical deployment of Microservices.

Why is there so much buzz about the Microservices approach?

If you’re planning a new software application of relative size and complexity there is a high chance its backend architecture will be built on microservices.

Relatively recent developments in software and hardware technologies have allowed for an application to be broken down into multiple simultaneous processes and services instead of consisting of a single monolithic architecture. As the architectural approach of designing software as suites of loosely coupled but independently deployable services was developed and gained in popularity, it started to be referred to as microservices architecture.

Microservices advantages

  • If you separate different components of an application into microservices, they can be developed simultaneously, accelerating the delivery process.
  • Components (service) being deployed across many servers makes maintenance easier and an app more reliable and easier to scale in the long term.
  • Unlike the classic approach of “monolith” applications, microservices architecture makes it much easier for new developers to join the software development team. They will quickly get up to speed with individual microservices and don’t have to worry about complex dependencies. With monolith apps, the larger they grow, the harder it gets for newcomers to get to grips with all their dependencies and intricacies.

Note, however, that following а microservices pattern is not a one-size-fits-all approach that should be implemented for any software system. In many of our projects at K&C, we combine microservices with CQRS, event sourcing and DDD patterns when designing the architecture of a new enterprise web application.

How and when we use microservices architecture

While a microservices architecture brings many benefits and cost advantages, one of the most important decisions to make is to decide how far you should go with the componentization of your application. You’ll have many arguments to consider, for instance:

Microservices pros

  • Iterative development – updating and reviewing the implemented functionality is easier due to the architecture’s clarity.
  • Flexibility – individual microservices can be developed in any programming language that best fits the need. While it still usually makes commercial and practical sense to stick to a particular tech stack, you have the flexibility to mix multiple languages, development frameworks, and data storage technologies if doing so offers clear advantages in the particular context.
  • Clarity – microservices mean software developers can concentrate on one particular module, or microservice, at a time. The independent codebase of a single microservice is relatively small meaning new developers can quickly understand the code and don’t have to worry about complex interdependencies with other code blocks.
  • Scalability –  microservice modules can be containerised and deployed across multiple servers to enhance performance and separate them from other services, reducing the impact of one point of failure. This is especially important for larger, more complex applications and means availability can usually be maintained even if one microservice goes down. In a monolithic architecture, there would be a high chance of dependencies between services that could mean a failure in one place could take down the whole app.

Microservices cons

  • Time consuming – one module interacts with another via REST API, making the development process slower than building a comparable app with a monolith architecture. Multiple microservices also increases the amount of work for DevOps engineers setting them up on servers, which can mean multiple servers, and keep the whole infrastructure balanced and running in a coordinated way.
  • Monitoring and testing more complicated – a microservices-based application has numerous independent services that have to be tested in potentially different server environments. The higher number of modules, the more complex it becomes to integrate the microservices and ensure efficiency.
  • Skill demands –  a higher level of expertise and experience is required to build a smoothly functioning app based on a microservices architecture compare to a comparable monolith architecture.
  • Higher upfront costs – a combination of the above downsides to microservices-based application inevitably increases the upfront costs involved. However, proponents argue that the advantages outlined above, especially when combined with superior performance, can often mean a microservices architecture is more cost-efficient than monolith over an application’s lifetime.

An example of a Microservices architecture gone wrong

While a microservices architecture offers many advantages, it is far from the case that it is always the right choice for every kind of app. And microservices also leave plenty of room for error when executed poorly. We had a case where a client came to us for help with an app that had been split into dozens of components. When things were going smoothly that granular approach led to strong performance indicators. But the development team maintaining the app were often faced with problems and bugs caused by improper interaction between the microservices.

In this particular case, the app had been overly-zealously broken down into more microservices than it should have been. Breaking down functionalities into too many microservices led to additional time and costs for maintenance, support, and updates instead of the inverse. And a lack of resources to handle those difficulties ultimately impacted on the app’s performance.

How we implement a Microservices architecture

1. Once the business logic of the future product has been defined, we prefer to start by breaking the app down into larger components that can later be again split out into more Microservices if advantageous.

2. Smaller parts of the original components that turn out to be critical in terms of performance can be split out as an autonomous service.

3. Proof-of-concept of the architecture proposed for implementation (or at least the most important parts of it) should be prepared and corner cases analysed.

4. We use well-known libraries and frameworks to minimize the costs of updating snapshot versions and dealing with bugs.

5. We stringently test services code and implement integration tests for API checks.

6. We build and use a well-organized continuous integration pipeline with “one-button” deploy and release.

7. We consider using Docker and Kubernetes to orchestrate services.

While such an approach may sound pretty straightforward, our experience shows this is the most cost- and time-efficient development strategy for most enterprise products.

Why microservices can be so effective

Most of our enterprise clients with large, complex applications where high availability is non-negotiable have a preference for a microservices architecture for the following reasons:

High availability

Since failure in one service does not affect other services you can be sure the whole app won’t go down just because of a small bug in the code of one component.

Scalability

Services providing critical functionality can be easily scaled to more servers (which can even be done on the fly), while monolith apps oblige you to invest time and resources into scaling the entire system at once.

Fast releases

Development can be done in parallel by different developers or teams which allows for adding new people quickly if the development process needs to be accelerated.

Future-proof

While Microservices architecture requires DevOps expertise in a development team, it makes deployment easier and more reliable, especially when using technologies like Docker.

Microservices architects and development teams

If you’d like to discuss a new software development project you think may benefit from a microservices architecture approach or are considering migrating a legacy monolith application to microservices, please do get in touch. We’d love to hear about it and offer you our assessment of the suitability of microservices in your particular context!

You might also be interested to read why and how we helped the world’s largest events company migrate their core enterprise multi-tenanted CMS from a monolith to microservices architecture.

K&C - Creating Beautiful Technology Solutions For 20+ Years . Can We Be Your Competitive Edge?

Drop us a line to discuss your needs or next project