What are Microservices?
A complete guide to microservices: learn the benefits, see examples, and understand microservices architecture
Why Microservices are Important
Understanding and embracing microservices and process automation are imperative to an enterprise’s competitive ability and continued success. This guide will focus specifically on microservices, defining what they are and exploring how they work. We’ll also talk about the role of the cloud in microservices, best practices when implementing a microservices architecture, and its relationship to process automation.
What is Microservices Architecture?
Microservices are a type of application architecture in which an application is composed of small, independent services that communicate over well-defined APIs. Each service is owned by a small, self-contained team responsible for the service’s design and implementation.
Using a microservices architecture allows teams to be more innovative and agile, developing and releasing new features more quickly.
Note: In this guide, we’ll use “microservices” and “microservices architecture” interchangeably because the term microservices is often used to describe microservices architecture.
Microservices Architecture vs. Monolithic Architecture
Microservices architecture and monolithic architecture are similar in that they are both capable of powering organizations and running applications, but they accomplish this differently.
In a microservices architecture, developers build independent components (or services), each intended to perform a single function. Communicating through an API, these microservices are built toward business capabilities. Because they are created and run independently, developers can easily change, update, and deploy microservices without touching other areas of the application. This means that developers can be more agile and innovative and can implement new features more quickly.
By contrast, in a monolithic architecture, functionality within the application is tightly intertwined with all other processes. Everything runs as a single service — which means that the entire architecture must be updated when a change needs to be made. Because everything is intertwined and connected, it’s difficult for developers to easily and quickly implement new features or functionality, limiting innovation. If one part of the monolithic architecture breaks, there’s a good chance the entire system will come to a halt, as all elements are tightly-coupled.
SOA vs. Microservices Architecture
Service-oriented architecture or SOA is a software development approach that uses reusable software components. Each component (or service) contains the code and data integrations the application needs to execute a particular business function, like checking the validity of a customer’s credit card during the online checkout process. Because they can reuse services and components in other applications throughout the enterprise, SOA saves development teams significant amounts of time.
If you think SOA sounds a lot like microservices architecture, you’re correct. Both architectures comprise loosely-coupled, reusable services that often work independently. But there are several differences, as well:
- Intent: Reusability of components is the primary goal of SOA; for microservices, the mission is “built for replacement,” focusing on team organization and the exchangeability of individual components.
- Communication: SOA services have to use an enterprise service bus (ESB) to communicate, while microservices each have their own communication protocol.
- Interoperability: SOAs tend to use heterogeneous messaging protocols like AMQP (Advanced Messaging Queuing Protocol) and SOAP (Simple Object Access Protocol). Microservices use simpler, lightweight messaging protocols like JMS (Java Messaging Service) and HTTP/REST.
- Speed: SOAs frequently operate more slowly than microservices architectures because they focus on sharing resources versus duplicating them.
How Does Microservices Architecture Work?
To understand how microservices work, it’s best to use an example. Imagine that your team is fully empowered to own a microservice around SIM card provisioning. You can freely choose your tech stack (staying within the boundaries of your enterprise architecture) and your team deploys and operates that service itself.
This allows you to implement or change the service at your own discretion, without having to ask others to do anything for you or join a release train. This means your team can quickly deliver changes while increasing their motivation, as owning their service makes team members feel empowered.
A microservices architectural style, however, does have an impact on process automation. Automating one business process typically involves multiple microservices. And unlike SOA that requires an orchestration process “outside” of the services to piece them together, microservices architecture doesn’t allow business logic outside of the microservices. Therefore, the collaboration between microservices is within the microservices themselves.
Microservices Architecture Example
Take for example a customer onboarding service. The microservice owns the business logic around onboarding, which includes the onboarding business process. The team implementing the microservice can decide to use a workflow engine and BPMN to automate that process, which then orchestrates other microservices. The decision is internal to the microservice and not visible from the outside; it is an implementation detail.
Communication between the microservices is done via APIs, and not through the BPM platform, as is the case with SOA. Processes are part of the business logic of a microservice; no central workflow engine is needed.
Containers vs. Serverless Microservices
Containers and serverless microservices are similar in that they both allow developers to create applications in the cloud, requiring less overhead than developing on a virtual machine or traditional server. But there are several differences:
- Cost: Containers are always running, meaning that the enterprise is billed for the space on the server even if the application isn’t in use. However, in serverless architecture, the application only runs when it is called, meaning that businesses are only charged for actual use of server capacity.
- Scalability: When developing in a container-based architecture, the developer determines, in advance, the number of containers that they will use; serverless microservices automatically scale as demand changes.
- Deployment speed: Containers require developers to determine settings, libraries, etc. — and once configured, they take seconds to deploy. Serverless applications take only milliseconds to deploy, allowing for changes to go live almost simultaneously with the code update upload.
In a container-based architecture, the onus for managing and updating containers falls on the shoulders of developers; in serverless architecture, the vendor handles all server maintenance and upgrades.
Common Microservices Architecture Patterns
An API gateway pattern is an integration pattern that serves as a single entry point between client apps and your microservices. It provides a buffer between the client’s needs and the system’s underlying services.
There are two main ways that developers can apply decomposition:
Decomposition by domain: In this method, developers define services that correspond to domain-driven design (DDD) subdomains, identifying the region where they will deploy the solution and the services needed for that region. Every subdomain relates to a specific part of the business, from device communication to user management.
Decomposition by module: In decomposition by module, developers define components based on modules or features. This allows different development teams to be responsible for each module.
Event Sourcing Pattern
An event sourcing pattern is an operational approach to handling data driven by an event sequence. In it, all changes to an application’s state are recorded in the order in which they were applied, creating an audit log. Event sourcing is a highly scalable, decentralized change handling approach.
Service Discovery Pattern
There are two general types of service discovery patterns: client-side discovery and server-side discovery.
Client-side discovery pattern:
The service client searches the registry, using a load balancing algorithm to identify an available, appropriate service interest. Then it makes a request. When the service starts, the server registry notes the instance’s location — and when it stops, the registry deletes the instance information.
Server-side discovery pattern:
Unlike client-side discovery, in server-side discovery, the client-side service consumers are oblivious to the service registry, instead making requests through a router. The router searches the service registry and forwards the request to the right place once the proper service instance is found. The API gateway chooses the right client-side request endpoint, making load-balancing a non-issue.
The aggregator pattern addresses how an application should aggregate the data each service returns and deliver the response to the consumer. The aggregator pattern handles this in one of two ways:
- The API gateway partitions the request to multiple microservices and aggregates data to send to the consumer, or
- A composite microservice calls each required microservice individually, aggregating and transforming the data before returning it to the consumer
Database or Shared Data
There are two main database architecture approaches to microservices:
Database per service: In this approach, every microservice has its own database available only to that service — it can only be accessed by the microservice API.
Shared database per service: While one database per service is the preferred approach for microservices, often, it is difficult to achieve when migrating from a monolith to microservices. In that situation, a shared database per service pattern provides a workable solution and a good starting point for breaking the application into smaller, more logical pieces.
How Do Microservices Communicate With Each Other?
When it comes to microservices communicating amongst themselves, there are two common messaging patterns:
Synchronous communication: The caller waits for a response from the receiver using a protocol such as HTTP or gRPC.
Asynchronous message passing: This microservice communication pattern doesn’t wait for a response; instead, one (or multiple) services asynchronously process the message.
Microservices Pros and Cons
Benefits of Microservices
Given multiple converging market pressures, organizations are accelerating the pace and increasing their investment toward transforming to become a truly digital enterprise. Enterprises pursuing digital transformation are scrambling to move to modern architectures incorporating the cloud, microservices and mobile applications.
Microservices architectures have become increasingly popular for their flexibility and agility — but those aren’t the only advantages. Other microservices benefits include:
Because they separate applications into smaller, independent components, applications are easier for developers to build and maintain. Developers can create, deploy, manage, and support every service independently, reducing the size of the codebase. Testing is more manageable, and teams can work on different areas of the application simultaneously.
Development teams can determine the best language or technology for each microservice without worries about incompatibility. They can independently scale individual services and add new components without the entire system needing to be redeployed.
Microservices make it easier for developers to pinpoint and fix the underlying cause of any performance issues. Because they’re individual services, a single failure doesn’t have to impact the larger application. It’s also easier for developers to make changes and roll back updates to a specific module without the need to redeploy the whole application.
Continuous integration/continuous delivery (CI/CD)
Microservices make it possible for cross-functional teams to troubleshoot, test, develop, update, and deploy services independently, shortening the overall development process lifecycle.
Download Our Additional Resource: 3 Common Pitfalls in Microservice Integration – And How to Avoid Them
Ease of Understanding
Microservices architecture is easier for developers to understand each service’s functionality.
Better Support for DevOps
Microservices architecture lets organizations separate applications into smaller services, allowing delivery teams to individually tackle services and streamline development, testing, and deployment.
Faster Development Cycles
Because microservices have both a smaller codebase and a more narrow scope, developers can quickly deploy new features and functionality.
Microservice architecture offers better fault isolation. The failure of a single microservice does not mean the system’s failure, as other microservices will continue to perform without issue.
Because microservices are individual, separate services, developers can scale critical services without having to scale the entire application.
Cons of Microservices Architecture
While microservices architecture has many advantages, it also comes with some disadvantages.
Because microservices are individual, it’s challenging to perform global testing; developers must confirm each dependent service before testing.
The sheer volume of the number of microservices can make it more difficult to share information across services.
A distributed system with a large volume of microservices can increase the application’s level of complexity.
If your enterprise is currently running a monolithic architecture, there will be up-front costs for your infrastructure (e.g., hosting, maintenance, security). You will also need developers for shifting to microservices.
Who Needs Microservices?
Many times organizations wonder who needs microservices? Are microservices right for our business? Below are some common situations where microservices may make sense for your organization:
- You’re creating agile applications that require optimal innovation and speed of delivery
- You’re ready to embrace an approach that facilitates agility, scalability, and manageability
- You find your business needing to rewrite/rework legacy applications to stay up-to-date with business requirements
- You have individual, standalone modules that need to be reused
Why Cloud Microservices Have Better Scalability
While microservices aren’t exclusive to a cloud environment, they are often used together. One of the main reasons for this is their inherent scalability. Because microservices can be individually deployed and scaled, they maximize the benefit of cloud computing’s pay-only-for-what-you-use infrastructure — reducing costs across the board. In addition, the flexibility of microservices can lead to complex tech stacks that present management challenges, but the vendor-managed cloud backend can help businesses reap the benefits of microservices without management headaches.
Watch On Demand: 3 Superpowers for Next Level Microservices Orchestration
How to Implement Microservices
Implementing microservices is a matter of two primary things: migrating from your existing monolithic infrastructure to a microservices architecture and then determining when to use commands and events to communicate, orchestrate and choreograph between services. Let’s take a closer look.
Migrating from Monolithic to Microservices
When you’ve decided to migrate from monolithic to microservices, there’s only one surefire way to go about it, methodically.
Decomposing a monolith comes down to three C’s:
- Capture – Identify which functionality to migrate to a microservice.
- Communication – Insert a proxy to intercept calls and divert them to the new microservice.
- Capabilities – Gradually shift functionality from the original monolith to microservices.
However, merely implementing microservices in place of a monolith isn’t a cure in itself – they aren’t some business panacea. As the number of microservices involved in a single business process increases, serious drawbacks can occur if you’re not careful. Orchestrating and monitoring business processes end-to-end can turn into a nightmare and severely limit scalability, eliminating any benefits the use of microservices may have had.
That makes it crucial to carefully think through and map your journey as you decompose your monolith and build upon your newly established architecture with microservices.
Microservices Orchestration vs. Choreography
When designing and implementing your microservices-based architecture, be open to using both commands and events to communicate between services. Choreography and orchestration offer different benefits and drawbacks — smart businesses incorporate both styles into their microservices architecture.
When an event occurs in the system (for example, an order is placed), microservices emit events without knowing which other microservices will act on them.
Microservices get notifications when event topics they’re subscribed to are active; they don’t know where the event came from.
Allows for microservice independence and developer team autonomy.
The event chain isn’t explicitly defined anywhere, making it nearly impossible to monitor or troubleshoot actions.
|When an event occurs in the system (for example, an order is placed), one microservice instructs another to take a specific action. One microservice controls the flow of activity, actions, and timing of other microservices.|
The sending microservice knows exactly which microservice will receive its command. Recipients can never ignore a command but can accept or reject them.
It reduces the service’s independence; the sending microservice has to know that the receiving microservice exists, check whether it’s running, wait for a response from it, etc.
Best Practices for Microservices Architecture
When implementing a microservices architecture, it’s worth following a few best practices to make the most of your investment.
Create a Separate Build for Each Microservice
Always create a separate build for each microservice so it can pull component files at appropriate requisition levels. While your microservices may end up pulling in similar file sets at different revision levels, it ensures that introducing new microservices is easy and doesn’t jeopardize the larger system.
There are many benefits to using a workflow engine to manage microservices:
Certainly, microservices give development teams unparalleled agility, allowing users to deliver updates without the need to rebuild and relaunch an entire application constantly. But the reality is that managing multiple microservices — each communicating with other microservices to complete processes — is necessary to make the most of your investment.
Camunda Platform and its workflow engine has complete visibility into all microservices, allowing it to manage and report on business processes effectively. Some businesses take things a step further, implementing many decentralized workflow engines across microservices, enhancing their development teams’ autonomy.
There are many benefits to using a workflow engine to manage microservices:
- Allows for instances to persist across states — beneficial during long-running processes (e.g., a multi-step payment process that takes days or weeks)
- Makes it easier for developers to find, understand, and modify business processes
- Coordinates and correlates messages across processes and determines next steps
- Compensates if problems occur, undoing previously-completed steps
- Tracks time and automatically acts/switches paths if messages don’t arrive on time
- Gives developers the ability to specify error path behavior
- Provides real-time process instance status reporting
Deploy in Containers
It’s easy to see how deploying thousands of microservices can become cumbersome, and that’s where containers come in. Containers mean that you only need one tool to deploy multiple microservices; as long as the microservice is in a container, the container knows what to do with it and how to run it.
Get Your Team Onboard
Shifting from a monolithic architecture to a microservices architecture can be tedious and time-consuming across business units. And while the increased ease of use and business agility may be worth it, the transition process may prove difficult. Work with stakeholders across the organization to get buy-in and help keep users apprised throughout the transition.
Design Microservices to be Loosely Coupled
Microservices architectures require services to be as loosely coupled as possible. However, loosely-coupled services have minimal dependency on other services, but they must have high cohesion and perform their function well.
Monitor, Monitor, Monitor
Do not “set it and forget it” when it comes to microservices; it’s crucial that you continually monitor microservice performance and resource availability. By doing this, you’ll be able to quickly identify compromised resources, enhancing security.
Leverage Domain-Driven Design
A design philosophy that says that code language and structure should mirror the larger business domain, domain-driven design puts the focus of the product on domain logic and the core domain. It creates a collaborative design process that allows technical and domain experts to communicate and iterate on a model that addresses problems across the business.
Use RESTful APIs
There’s no denying that APIs are a requirement for any microservices architecture to communicate between individual services. Choose RESTful APIs to build your microservice’s interfaces; it’s based on open networking principles and provides the best model.
Table of Contents
Need Help Getting Started?
View resources for beginners, experienced users, and everyone in between.