Microservices are small applications that perform a single service and communicate with each other via application programming interfaces (APIs).
A developer can assemble microservices into a larger complete application but still update, improve, and maintain microservices individually. This independence allows developers to add or improve functionality (or troubleshoot and repair application issues) faster than they can in a "monolithic" application architecture, in which the application is developed, updated, or repaired as a single unit. The independence of the individual microservices allows changes to executed or rolled back without impairing the application's function as a whole.
Microservices offer developers a number of benefits:
Greater independence: Each microservice is independent of the others—it can be upgraded, changed, repaired, or removed without having adverse impacts upon the overall application or development process. This independence promotes end-to-end ownership among development teams, allowing each team to work more efficiently.
Shorter deployment cycles: Microservices development teams act autonomously. They focus only on the functionality and within the defined framework of the microservices they develop. This allows teams to work faster and implement changes and upgrades sooner.
Easier innovation: Because microservices themselves and the teams who create them are independent of each other, there is a low cost of failure. Teams can quickly test and try ideas. If changes fail, you can roll them back to previous iterations.
Better fault isolation: If one microservice fails, it does not impede the function of other microservices or of the application as a whole.
Greater agility and scalability: Since each microservice stands on its own, it can be used and re-used as a component of any number of applications. This modularity makes it easier to scale components horizontally (more machines added to the same pool of resources) and vertically (increasing the power or capacity of a machine by adding resources).
Before you embrace the microservices architectural model, weigh the pros and cons.
Ensures the right tool for the job: Reliance on microservices architecture allows a developer to compose a specific toolset that solves a business need rather than choosing a one-size-fits-all approach that provides an approximate fit or only partially answers the need.
Simplifies deployment: With microservices, you can create, update, and deploy a single service independently of the rest of the system. You can isolate deployment, which does not impede the functionality of the application. If the service update fails for some reason, automation can roll back the update, isolating the impact.
Enables continuous integration/continuous delivery (CI/CD): Each microservice is independently deployable. That means all types of changes—improvements, bug fixes, added features, added functionalities—can be quickly and safely rolled into production at any time. Development teams can construct automated CI/CD pipelines to make this process even easier.
Future-proofs your organization: Monolithic legacy systems have become a burden on many organizations. They are so entwined into the operation of a company that getting rid of them seems impossible. Shifting toward a microservices architecture prevents that sort of entrenchment from taking place. Since systems are composable and decentralized, you can constantly replace, improve, or even remove microservices without creating significant impact or risk.
May require organizational change: Small teams independently create, develop, and maintain each microservice. Teams must act independently and take ownership of the microservice over its entire lifecycle. It may take time to transition teams to this new way of operating and thinking.
Makes management complex: Microservices mean to more parts, more pieces, and more teams that require oversight and management. That also means more opportunities for testing, security, and communications to break down or fail.
Can create more problems than it solves: Your monolithic applications may not easily break down into microservices. You might not understand the full relationship between an application's various parts. When separated into multiple services, this may create a distributed and decentralized behemoth that is far more difficult to manage than the monolithic application had been.
Complicates testing: In a distributed and decentralized architecture, testing is more difficult. Teams must ensure that changes made to a microservice don't negatively impact other services or the application as a whole. You might require automation so that if upgrades or improvements fail, the service automatically falls back to the previous version of the service.
When you should and shouldn't use microservices
When to use
You should use microservices when you need fluidity, flexibility, and scalability for your cloud applications. The goal should be to adapt applications to industry, user, and market demands by delivering a constantly improving service. Microservices work best in organizations that use agile and DevOps practices and have teams skilled in application architecture.
Microservices may not be the best option for your organization if you don’t operate in a highly competitive field that must adapt quickly to user or market demands. Many organizations might find microservices too disruptive and complex to manage. In those cases, you could see little to no return on investment for the effort. If your company’s development teams do not already use agile or DevOps practices, using the microservices architectural model will require a cultural change.
Microservices and cloud-native
Cloud-native applications operate only in the cloud, using only cloud resources. Developers often build these applications using microservices architecture to integrate into cloud environments. Microservices architecture offers advantages to cloud-native applications by making them easier to reconfigure and refactor to suit specific business needs. Microservices enable frequent, iterative updates that constantly improve the cloud-native application experience for end users.
Serverless computing does not mean computing without servers; it refers to a cloud computing model in which the developer creates the code and lets the cloud provider provision and manage the server resources required to run the code.
Serverless computing is also known as Function as a Service (FaaS)—although generally, microservices are larger than and do more than a function, which is a small bit of code that performs one function in response to an event. A microservice can equal a single function or comprise multiple functions.
You can build serverless microservices that run only when needed by an application. Because they run in a serverless environment, the underlying infrastructure lasts only as long as the function requires. You might choose this option when you need as little operational overhead as possible for your application.
You can also replace microservices with serverless functions. Because microservices tend to be larger than serverless functions, you may find it beneficial to remove microservices by breaking them into functions. This provides more modularity and agility to your code. However, this may add to the complexity of your applications by creating more parts to manage.
Think of microservices and serverless computing as tools. Both have separate uses but can, in some cases, be used together or in place of the other. The options and tools you choose depend on the needs you have.
A microservices architecture enables continuous, rapid delivery and deployment of applications. Not surprisingly, some of the biggest names in tech, entertainment, and retail employ microservices architecture. Netflix was one of the earliest adopters of this architectural model as it broke from its monolithic DVD rental application into a digital streaming entertainment service while openly documenting the process. This helped popularize the model. Many other large companies—such as eBay, Twitter, PayPal, and Uber—followed a similar path.
Microservices architecture vs. service-oriented architecture (SOA)
Like microservices, service-oriented architecture SOA breaks down applications into services; but as the name suggests, these services aren’t as granular as microservices. The SOA approach to software development first defines application goals and then the approaches that will meet those goals. Applications built with SOA focus on business functions and place greater emphasis on governance standards across applications. Because SOA components are larger, they require more coordination between development groups to implement changes. While microservices are independent modules, SOA components are more interdependent. SOA can be considered the middle ground between monolithic applications and microservices.
Whether an organization chooses an SOA or microservices approach may depend on the nature of its business services and how often they change. A bank with well-defined, rarely modified cash management processes may choose the SOA approach to modernize its legacy systems. However, a global retailer might need a more granular, microservices-based approach for its systems, since a retailer must be more adaptable to customer and market demands.
For example, if the retailer's aging architecture crashes during a sales spoke, it must address those crashes or risk losing business. SOA-based systems may be less able to respond to traffic surges that approach millions of page views per minute. The retailer could choose to replatform its systems using microservices architecture to break down legacy apps into far more simplified services. That modularization would make traffic easier to manage and equip customers to use the website on mobile devices.
The granularity also makes implementing future changes easier and less disruptive. And you can make those changes quickly, even during hectic sales events.
Event-driven architecture views applications as systems that react to events. Those events may occur in the outside world and cause a reaction or change to the system. Or, the event may occur within the application, causing the application to announce changes to itself to an outside system.
Suppose a customer orders an item from a retailer. A reaction to that order might be for the system to note that inventory has changed and that ordering more goods to replace that inventory might be necessary. An outside event occurred (the customer’s order) which caused a change to the system (the number of goods on hand) which then caused an internal system to announce that change to another system (notice that inventory changed and that replacing that inventory might be necessary).
The distributed nature of microservices enables communications between event-driven systems, making them responsive to events while also maintaining system independence. That independence means microservices can be improved, updated, or replaced without an adverse impact on any single system.
Microservices patterns offer reusable solutions to common problems that developers run into when creating microservices. Patterns help developers implement microservices faster and create resiliency in applications. Many pattern types exist. This section only describes a few:
Single page application (SPA) pattern: An SPA interacts with a user by dynamically rewriting the content on the single page rather than loading all new pages. Dynamic service calls update parts of the screen based on user input.
Backend for frontend (BFF) pattern: This pattern type inserts a layer between the user experience and the resources that experience calls on. For example, an app used on a desktop will have different screen size, display, and performance limits than a mobile device. The BFF pattern allows developers to create and support one backend type per user interface using the best options for that interface, rather than trying to support a generic backend that works with any interface but may negatively impact frontend performance.
Entity and aggregate patterns: An entity is an object distinguished by its identity. For example, on an e-commerce site, a Product object might be distinguished by product name, type, and price. An aggregate is a collection of related entities that should be treated as one unit. So for the e-commerce site, an Order would be a collection (aggregate) of products (entities) ordered by a buyer. These patterns are used to classify data in meaningful ways.
Service discovery patterns: Service discovery patterns help applications and services find each other. In a microservices architecture, service instances change dynamically due to scaling, upgrades, service failure, and even service termination. These patterns provide discovery mechanisms to cope with this transience. Load balancing may use service discovery patterns by using health checks and service failures as triggers to rebalance traffic.
Adapter microservices pattern: Think of adapter patterns like plug adapters that you use when you travel to another country. The purpose of adapter patterns is to help translate relationships between classes or objects that are otherwise incompatible. An application that relies on third-party APIs to function might need to use an adapter pattern to ensure the application and the APIs can communicate.
Strangler application pattern: These patterns help manage refactoring a monolithic application into microservices applications. The colorful name refers to how a vine (microservices) slowly and over time overtakes and strangles a tree (a monolithic application).
Software architecture approaches have changed over time, evolving from the traditional monolithic approach to the service-oriented architecture (SOA) approach and now to microservices architecture.
Monolithic vs. microservices
Monolithic architecture refers to self-contained software developed with all application code and the user interface bound to one platform. Since it is all one piece, if any part of the application requires an update, you must update the entire application. Because of this, there can be long waits between application updates. Microservices architecture is the opposite of this in that a larger application is built from a loosely coupled collection of smaller applications that each perform a single service.
As noted above, the SOA approach to application architecture breaks down applications into services that are not as granular as microservices. Many view microservices as a logical evolution of SOA.
Microservices and other modern technologies
Microservices link with many modern-day application development technologies.
Microservices vs. containerization
The combination of containers and microservices often enhances cloud capabilities. Containers efficiently package and manage application resources, including microservices. Containerizing microservices isn’t required but it can make deployments faster, easier, and more agile. It can also make configuration and provisioning less prone to errors since needed resources are packaged together.
It's possible to view microservices and serverless computing as distinct toolsets. They can be used together, but they do not have to be. Sometimes serverless computing, also known as Function as a Service (FaaS), replaces microservices by breaking services down even further. Some developers find this beneficial because it adds even more agility and modularity to code but can add complexity by adding more parts that must be managed.
Microservices languages and frameworks
Developers continue to debate if Java is the best option for microservices development. Proponents believe it's a good choice for the following reasons:
Many developers know the language
As a mature language, there's a deep well of knowledge that can be tapped
Many Java microservices frameworks already exist
It's a stable platform
Even if you choose a language other than Java, microservices development is pretty forgiving. You can test other languages without making any major investments.
Microservices frameworks provide developers a standard way to build and deploy microservices applications. Each development language includes these frameworks. They offer tools, code libraries, APIs, and user support to make microservices development easier and faster.
How to build microservices
Successfully building microservices requires more planning than coding. To build microservices, start with the business need you want to solve. What kind of application would be required to address that need? Start by listing the application features required. Then, break those features down into specific functions and services. Once you've defined each service, clarify the dependencies and relationships between them. How will each service interact and coordinate?
Having this clarity about system organization will help clarify team organization. Team structure matters because small teams independently build, manage, and maintain microservices. You need teams equipped to manage the full lifecycle of microservices development.
Once you've identified service areas and the teams responsible for each, the next step is building. There are multiple frameworks and platforms on which to build microservices. The approach you choose depends on the application type and your team's development experience. No matter what approach you take, you need to ensure teams have well-defined boundaries and keep open lines of communication to ensure services continue to interact as expected. Microservices architecture, because it is decentralized, offers multiple points of failure.
Ensure your system is designed to account for and recover from those failures. Monitoring also becomes more complicated with microservices architecture, but is essential to ensure operational and functional issues are identified and fixed as quickly as possible. In short, building microservices architecture is an iterative process. It takes time, planning, and practice to execute successfully.
Although microservices don't require containers, they are often used together. Containers and microservices both simplify and improve the development process, yet they also have more moving parts that must be managed. Container orchestration tools, like Kubernetes, help manage this complexity. These tools allow you to deploy, scale, and manage your containers. These tools allow for automation, making it easier to manage the various application components.
"Istio: A Complete Guide," gives a comprehensive overview of another tool that facilitates the managing of microservices.
Microservices development and best practices
Microservices development differs significantly from other architectural approaches, such as monolithic and SOA development models. Use best practices as you create microservices applications:
Ensure good communications from the start: Microservices development is decentralized and application components are only loosely coupled. Ensure you have strong communications in place between development teams
Test early and often: As you build new cloud-native apps or begin to refactor monolithic apps, you may be surprised at the dependencies that surface between microservices or are revealed within legacy apps. Develop a frequent testing process so that failures can be address quickly or code can be rolled back to earlier versions.
Manage complexity: Microservices create many moving parts. Although this architectural model simplifies many things, it also complications the application environment. Use automation and orchestration tools to help manage complexity.
These videos show examples of companies that are putting the microservices architectural model to use:
American Airlines built a dynamic rebooking app, launched during a severe weather pattern. The airline used microservices to break its problems into much smaller problems and recognized that microservices technology must be part of its strategy to deliver the level of service that customers demand. The app improved customer experience by providing users more information and an improved rebooking process.
Bernhardt Furniture replaced its administrative monolithic backend with a microservices architecture to better meet user and customer demands. The company’s Virtual Showroom transitioned from a monolithic app to a microservices app and now allows customers to explore more product and personalization options than they can view on the sales floor. The shift allows Bernhardt to focus on the customer experience and personalization and has resulted in 20% more customer engagement and a 20% increase in sales.
Eurobits provides bank account information services, helping banks work with customers to manage their accounts. Part of the company’s cloud migration strategy is containerizing its applications. Eurobits uses Java-based microservices in containers to significantly accelerate every stage from development to production. Using microservices and a container-based approach allowed the company to better utilize its IT resources and improve application performance.
If you're ready to learn more about how to use microservices, or if you need to build on your microservices skills, try one of these tutorials:
Microservices enable innovative development with a speed to match modern-day business demands. Learn how to capture the scalability and flexibility of the cloud by deploying independent microservices into cloud environments. Free your development teams by using a model that relies on automated iteration to speed new features and updates to your applications using IBM cloud-native development tools.