Design Patterns for Microservices and Containers
- Summary
-
Discussion
- What's the motivation for adopting design patterns for microservices?
- What are the elements of a good container design pattern?
- What are the common design patterns for microservices?
- Since there are so many patterns, which ones are important or essential to know?
- Could you explain patterns for running two containers on a single node?
- Are there patterns to manage data in a microservices architecture?
- Milestones
- References
- Further Reading
- Article Stats
- Cite As
For common software design problems, design patterns provide reusable solutions. Rather than design a solution from scratch, it's faster and easier to understand the context and see what design patterns can be reused for your application.
For a cloud application that uses containers and microservices, there are patterns to do the same. Called either Design Patterns for Microservices or Container Design Patterns, we use these terms interchangeably in this article.
Let's note that this article is not about container data structures or components. In programming, containers are data structures such as sets and queues that contain other data members. Such containers have design patterns too.
Discussion
-
What's the motivation for adopting design patterns for microservices? Sometimes there's a need to scale your monolithic application, to release updates faster or to manage large teams of diverse skills. One approach is to re-architect your application into a bunch of microservices that get deployed on the cloud as containers. This refactoring can be a long process for a complex product. It can also be daunting for folks new to the microservices architecture.
This is where design patterns can help. These patterns have evolved from best practices that engineers used when managing microservices and containers. When solutions to problems are known, they can be applied to similar problems in the future. Patterns formalize this concept of reusable solutions.
Patterns help you to build your apps faster and make them more reliable. Moreover, you may able to use libraries or tools–Amalgam8, Hystrix, Eureka, Zuul –that have already implemented some of these patterns.
-
What are the elements of a good container design pattern? A design pattern must be clearly described with concrete examples and best practices. Without a clear understanding, others will not be able to apply or even know if it suits their application needs. The pattern must be agnostic of container runtimes or cloud infrastructure.
For any pattern to be practical, it's necessary that the containers themselves are properly designed. Container design principles can be applied in two different contexts:
- Build time: single concern, self-containment, image immutability
- Runtime: high observability, lifecycle conformance, process disposability, runtime confinement
From the perspective of delivering software-as-a-service, similar principles have been noted in Heroku's The Twelve-Factor App.
-
What are the common design patterns for microservices? There are dozens of design patterns for microservices that can be grouped by categories such as decomposition, observability, testing, UI, communication, database, security, deployment, and so on. Google engineers identified the following in their work with Kubernetes:
- Single container management: graceful termination, probing, config maps
- Single node multi container: sidecar, ambassador, adapter
- Multi node: leader election, work queue, scatter/gather
Microsoft has published a number of design patterns including ambassador, backends for frontends, CQRS, event sourcing, gatekeeper, gateway aggregation, sidecar, strangler, throttling, etc. Other patterns to note are model, denormalizer, ingestor, service registry, edge controller, API gateway, circuit breaker, fallback, command, bounded context and failure as a use case.
-
Since there are so many patterns, which ones are important or essential to know? It's hard to claim that one pattern is more important than another. It all depends on the context and the needs of a particular application. However, we can highlight the following patterns:
- API Gateway: Clients call your application via command-line tools or GUI. Rather than call each service of your app separately, all calls will go via the gateway.
- Service Registry: Since microservices are created and destroyed dynamically based on load, this pattern helps in connecting clients to available instances of microservices. Microservices register with the service registry.
- Circuit Breaker: When a service is down, this failure could cascade to other services dependent on it. To prevent escalation, if failures exceed a certain threshold, services will not repeatedly call a failed service until recovery happens.
- Fallback: Also called Chain of Responsibility pattern, if a service is unable to complete because of a dependency, a fallback method is called. By combining fallback pattern with circuit breaker pattern, more resilient apps can be built.
-
Could you explain patterns for running two containers on a single node? Let's look at three patterns that each involve two closely associated containers. It makes sense to pair containers within the same node (or same Kubernetes pod) if they have the same lifecycle. One of them is the main container while the other can be seen as a helper. We explain them as follows:
- Sidecar: To provide an auxiliary service to the main container, such as for logging, synchronizing services, or monitoring.
- Adapter: To standardize or normalize the output/input/interface between the main container and the external world, such as reformatting logs or invoking libraries that don't have expected language bindings.
- Ambassador: To connect the main container to the outside world, such as for proxying localhost connections to outside connections. For example, main container will always see a localhost database with the ambassador resolving this to the actual database outside.
-
Are there patterns to manage data in a microservices architecture? For easiest migration from a monolithic app, all services could share the same database. For better isolation and modularity, we can adopt private-tables-per-service and schema-per-service, perhaps on the same database server. For high throughput requirements, each service could have its own database server.
One challenge with microservices is to ensure data consistency across all services. An important principle is to have a single authoritative source of truth: all others are read-only and non-authoritative. Services can synchronously query for data or asynchronously update it via events when that data changes. Whether to use synchronous API or asynchronous messaging depends on your application since both have their trade-offs.
An event-driven architecture using publish-subscribe model aids asynchronous updates. Store only what a service needs. If services are constantly exchanging data, you might want to rethink service boundaries.
A transaction that involves multiple services is not easy to implement. Some patterns are available: Saga Pattern, API Composition, Command Query Responsibility Segregation (CQRS), Scheduler Agent Supervisor, and Compensating Transaction.
Milestones
References
- Atchison, Lee. 2018. "Microservice Architectures: What They Are and Why You Should Use Them." Blog, New Relic, August 22. Accessed 2018-10-08.
- BPSE. 2013. "Container Pattern." Blog, Best Practice Software Engineering, October 04. Accessed 2018-10-05.
- Betts, Thomas and Randy Shoup. 2018. "Managing Data in Microservices." InfoQ, April 16. Accessed 2018-10-07.
- Brown, Kyle G. 2016. "Beyond buzzwords: A brief history of microservices patterns." IBM, November 30. Accessed 2018-10-08.
- Burns, Brendan and David Oppenheimer. 2016a. "Design patterns for container-based distributed systems." The 8th Usenix Workshop on Hot Topics in Cloud Computing (HotCloud '16), July 10-11, Santa Clara, CA. Accessed 2018-10-05.
- Burns, Brendan and David Oppenheimer. 2016b. "Container Design Patterns." Blog, Kubernetes, June 21. Accessed 2018-10-05.
- DeBenedetto, Sophie. 2016. "The React + Redux Container Pattern." The Great Code Adventure, November 16. Accessed 2018-10-05.
- Fowler, Martin. 2004. "StranglerApplication." Accessed 2018-10-08.
- Hohpe, Gregor. 2018. "Gregor Hohpe." Accessed 2018-10-08.
- Ibryam, Bilgin. 2017. "Principles of container-based application design." Whitepaper, Red Hat Consulting. Accessed 2018-10-07.
- Ibryam, Bilgin. 2018. "The Kubernetes Effect." InfoQ, February 07. Accessed 2018-10-05.
- Keyhole Software. 2017. "Microservices: Patterns for Enterprise Agility and Scalability." Whitepaper, Keyhole Software. Accessed 2018-10-07.
- Lewis, James and Martin Fowler. 2014. "Microservices." March 10. Updated 2014-03-25. Accessed 2018-10-08.
- Lübken, Matthias.2015. "Container patterns." goto; conference, Berlin. Accessed 2018-10-07.
- Microsoft Docs. 2017a. "Cloud Design Patterns." Architecture Patterns, Azure, June 23. Accessed 2018-10-05.
- Microsoft Docs. 2017b. "Designing microservices: Data considerations." Architecture, Azure, August 12. Accessed 2018-10-05.
- Microsoft Docs. 2017c. "Designing microservices: Interservice communication." Architecture, Azure, August 12. Accessed 2018-10-07.
- Osnat, Rani. 2018. "A Brief History of Containers: From the 1970s to 2017." Aqua Blog, March 21. Accessed 2018-10-08.
- Palmer, Matthew. 2018. "Multi-Container Pod Design Patterns in Kubernetes." June 09. Accessed 2018-10-05.
- Richardson, Chris. 2017a. "Pattern: Database per service." Accessed 2018-10-07.
- Richardson, Chris. 2017b. "Pattern: Microservice Architecture." Accessed 2018-10-07.
- Scott, Patrick Lee. 2018. "Learning these 5 microservice patterns will make you a better engineer." Hackernoon, January 12. Accessed 2018-10-08.
- Taibi, Davide, Valentina Lenarduzzi, and Claus Pahl. 2018. "Architectural Patterns for Microservices: A Systematic Mapping Study." 8th International Conference on Cloud Computing and Services Science, March. Accessed 2018-10-05.
- Wiggins, Adam. 2018. "The Twelve-Factor App." April 09. Accessed 2018-10-08.
Further Reading
- Microsoft Docs. 2017a. "Cloud Design Patterns." Architecture Patterns, Azure, June 23. Accessed 2018-10-05.
- Scott, Patrick Lee. 2018. "Learning these 5 microservice patterns will make you a better engineer." Hackernoon, January 12. Accessed 2018-10-08.
- Ibryam, Bilgin. 2018. "The Kubernetes Effect." InfoQ, February 07. Accessed 2018-10-05.
- Meléndez, Christian. 2018. "7 container design patterns you need to know." TechBeacon, May 10. Accessed 2018-10-05.
Article Stats
Cite As
See Also
- Migrating from Monolithic to Microservices Architecture
- Inter-Service Communication for Microservices
- Container Design Principles
- Container Orchestration
- Containerization
- Microservices