Many companies are now using microservices for both re-architecting existing applications and for starting brand-new projects and initiatives, and they’re investing heavily in doing so. In one survey by Red Hat, 87% of respondents indicated they are using or considering multiple technologies for developing microservices.
It would be prudent for these companies to first take a good look at the benefits and challenges associated with microservices architectures so that they know what they’re in for.
But first—let’s define the term “microservices.”
What are Microservices?
Microservices are an approach to software architecture that break large applications into smaller pieces. As with many architectural decisions, the decision to use microservices is not cut and dried and most likely will involve some trade-offs.
Here are some of the pros and cons of a microservices architecture:
After weighing out these pros and cons in the context of a specific system’s requirements, a decision about whether to use microservices can be made. It’s not the right solution for every system. But, if you’ve been running into a wall trying to accomplish some of the things that microservices provide, it can be a godsend.
Microservices Challenges and Benefits – An Example
Let’s look at a specific example showing the challenges and benefits of using microservices.
Imagine you have an ecommerce application with four main features: 1) a product catalog, 2) a shopping cart, 3) an affiliate program, and 4) customer profile management, and you have a single “monolithic” service that supports all of these features.
Your system might look like the following diagram. You can scale out your system by adding multiple instances of your application, and you can take all of your incoming traffic and balance those requests across all of your services.
However, you also have some issues:
- There are few people at your company who understand the service top to bottom. New hires in engineering take several months to become effective.
- As your company has grown, your application has become more and more complex with many interdependencies. It is difficult to deploy new versions of your service because it requires extensive testing to make sure that all the pieces of the application work together seamlessly.
- You are deploying more and more copies of your applications to handle spiking traffic from your affiliate clickstream, even though the other parts of your traffic are relatively predictable and stable.
Now, suppose you break this single application into four microservices, one for each feature (product catalog, shopping cart, affiliate program, and customer profile management). By doing so, the following changes are enabled:
- Your engineering staff is broken into four separate teams; each team is responsible for knowing their microservice.
- The product catalog team decides they want to use search technology to power their product catalog, rather than a relational database system; likewise, the team running the affiliate system decides to use a NoSQL database to store their time-series data; and the shopping cart team decides to host their data in a SaaS-based ecommerce system.
- The team that handles system deployments adopts a new scaling strategy and is able to scale instances of the affiliate microservice separately from other microservices.
Our new, microservices-based system might look like the following diagram:
The benefits we’re reaping from our microservices architecture are wonderful.
However, there are some new challenges introduced. Because our data is now distributed between systems (and even different databases), some operations are not as simple as they were before.
For instance, to make sure that we have data integrity between our systems, we can no longer rely on a relational database transaction (i.e., "BEGIN TRAN/COMMIT TRAN") to make sure that data is consistent between tables; instead, we have to look at other mechanisms that are enforced in our application tier, not in the data tier.
Or, something as simple as joining two tables together to get an aggregate view of data cannot be done anymore (how would you join a relational database table to a search engine?). Again, we have to accomplish the aggregation of data via application-layer mechanisms.
Microservices Trade-offs – The Bottom Line
In order to minimize the impact of these types of challenges, it is really important to understand your access patterns and use cases up front and to define the boundaries between your microservices thoughtfully. This is the most important piece of designing an effective microservices architecture.
I recently attended a lecture given by Martin Fowler, a tech thought leader who was one of the first folks to speak about microservices. Someone in the audience asked him, "What's one of the biggest problems with microservices?” Martin replied, "The fact that people are doing them." After some nervous laughter from the audience, Martin further explained that microservices only make sense at a certain scale and complexity; he said that small companies with small systems do microservices in an effort to solve problems that don't exist yet.
Microservices architectures—like most technology architecture decisions—involve trade-offs. It's important to understand what problems they solve and what new problems they introduce, and then, with a solid understanding of your requirements, apply them where they make sense.