Go Fast by Going Micro: Microservices Design Patterns You Should Know
Microservices design patterns are software design patterns that generates reusable autonomous services. The goal for developers using microservices is to accelerate application releases. By using microservices, developers can deploy each individual microservice independently, if desired.
They have their strengths and drawbacks (thankfully more strengths) and there are many more examples of when they are appropriate to use than not. Here are some listings of top microservices and their use cases we found in the blog-iverse.
This post is a nice fundamental rundown of some of the basic microservice design patterns. It’s a little older, but still germane. Post author Arun Gupta writes, "The main characteristics of a microservices-based application are defined in Microservices, Monoliths, and NoOps. They are functional decomposition or domain-driven design, well-defined interfaces, explicitly published interface, single responsibility principle, and potentially polyglot. Each service is fully autonomous and full-stack. Thus changing a service implementation has no impact to other services as they communicate using well-defined interfaces. There are several advantages of such an application, but it’s not a free lunch and requires a significant effort in NoOps."
Then Gupta lists several microservices design patterns he has found tried and true over the years:
"Aggregator Microservice Design Pattern: The first, and probably the most common, is the aggregator microservice design pattern. In its simplest form, Aggregator would be a simple web page that invokes multiple services to achieve the functionality required by the application.
Proxy Microservice Design Pattern: Proxy microservice design pattern is a variation of Aggregator. In this case, no aggregation needs to happen on the client but a different microservice may be invoked based upon the business need. Just like Aggregator, Proxy can scale independently on X-axis and Z-axis as well. You may like to do this where each individual service need not be exposed to the consumer and should instead go through an interface.
Chained Microservice Design Pattern: Chained microservice design pattern produce a single consolidated response to the request. In this case, the request from the client is received by Service A, which is then communicating with Service B, which in turn may be communicating with Service C. All the services are likely using a synchronous HTTP request/response messaging.
Branch Microservice Design Pattern: Branch microservice design pattern extends Aggregator design pattern and allows simultaneous response processing from two, likely mutually exclusive, chains of microservices. This pattern can also be used to call different chains, or a single chain, based upon the business needs.
Shared Data Microservice Design Pattern: One of the design principles of microservice is autonomy. That means the service is full-stack and has control of all the components – UI, middleware, persistence, transaction. This allows the service to be polyglot, and use the right tool for the right job. For example, if a NoSQL data store can be used if that is more appropriate instead of jamming that data in a SQL database.
Asynchronous Messaging Microservice Design Pattern: While REST design pattern is quite prevalent, and well understood, but it has the limitation of being synchronous, and thus blocking. Asynchrony can be achieved but that is done in an application specific way. Some microservice architectures may elect to use message queues instead of REST request/response because of that."
He goes into greater detail in his post. Check it out if you’re looking for a good primer on microservices design patterns.
Naturally the Azure team at Microsoft has just published nine new microservices design patterns. Mike Wasson, lead content developer for AzureCAT patterns and practices, describes the new offerings from the Azure team in this recent post.
The AzureCAT patterns & practices team has published nine new design patterns on the Azure Architecture Center. These nine patterns are particularly useful when designing and implementing microservices. The increased interest in microservices within the industry was the motivation for documenting these patterns. For each pattern, we describe the problem, the solution, when to use the pattern, and implementation considerations. Here are the new patterns:
Ambassador can be used to offload common client connectivity tasks such as monitoring, logging, routing, and security (such as TLS) in a language agnostic way.
Anti-corruption layer implements a façade between new and legacy applications, to ensure that the design of a new application is not limited by dependencies on legacy systems.
Backends for Frontends creates separate backend services for different types of clients, such as desktop and mobile. That way, a single backend service doesn't need to handle the conflicting requirements of various client types. This pattern can help keep each microservice simple, by separating client-specific concerns.
Bulkhead isolates critical resources, such as connection pool, memory, and CPU, for each workload or service. By using bulkheads, a single workload (or service) can’t consume all of the resources, starving others. This pattern increases the resiliency of the system by preventing cascading failures caused by one service.
Gateway Aggregation aggregates requests to multiple individual microservices into a single request, reducing chattiness between consumers and services.
Gateway Offloading enables each microservice to offload shared service functionality, such as the use of SSL certificates, to an API gateway.
Gateway Routing routes requests to multiple microservices using a single endpoint, so that consumers don't need to manage many separate endpoints.
Sidecar deploys helper components of an application as a separate container or process to provide isolation and encapsulation.
Strangler supports incremental migration by gradually replacing specific pieces of functionality with new services."
Wasson concludes with his own take on the whys and hows of microservices design patterns. "The goal of microservices is to increase the velocity of application releases, by decomposing the application into small autonomous services that can be deployed independently. A microservices architecture also brings some challenges, and these patterns can help mitigate these challenges."
Posted by Lafe Low on 02/28/2018