A Holistic Microservices Architecture Guide
As a software architect who actively writes code, I often find myself context switching between high-level architecture concepts and lower-level technical implementation details. This switching can often lead to unnecessary cognitive overload.
Comprehensive architecture reference guides, such as the one presented by Rag Dhiman in his Pluralsight course Microservices Architectural Design Patterns Playbook, help combat this overload and keep me efficient and focused when going from architecture to implementation.
Below is my very brief (and biased) summary of Rag's 17 point playbook:
- Use the Domain-Driven Design principals of Bounded Context and Ubiquitous Language to size and scope microservices.
- Asynchronous communication between microservices generally improves the performance and responsiveness of your service ecosystem. The industry prefers an event-based approach, utilizing patterns such as Fanout and Competing Workers.
- REST is the preferred solution for providing API-based microservices. We can take advantage of the Facade, Proxy and Stateless Server patterns to further enforce RESTful principals.
- The Broker Composition pattern, which further specifies asynchronous communication, is a great way to compose microservices.
- In a distributed environment where microservices communicate asynchronously, embracing Eventual Consistency is preferable. However, if you need to provide a higher level of data consistency, you can employ patterns such as Saga or Two-Phase Commit.
- API Gateway is the industry-standard pattern for centralizing access to API-based microservices. Also, API Gateway can provide necessary infrastructure functions such as tracing, monitoring, load balancing, and security.
- When designing databases for your microservices, avoid the traditional approach to data modeling which often results in monolithic databases. Instead, focus on Bounded Context for structuring tables/document collections and relationships. Each microservice should have an associated DB that enforces the Bounded Context.
- There are a number of patterns to improve the resiliency of communication between microservices. The main patterns described here are Bulkheads, Circuit Breaker, Retry and Timeout.
- To ensure backward compatibility of API's, make sure to come up with a versioning strategy and a plan for automated contract testing.
- Interface definition languages, like Swagger, provide a great solution for live documentation of your microservices.
- Centralized logging is a must when providing distributed microservices. In addition, consistently structured logs allow for easy access to and querying of logs.
- A number of patterns are available for handling reporting in a microservice ecosystem. Among them are Reporting Event Subscribers and Extract-Transform-Load (ETL).
- Continuous integration and delivery plans are a must for all microservices architectures.
- When it comes to cloud, a company will need to choose how and when to leverage PAAS, IAAS and SASS products. Often these products and on-premise software can be composed using asynchronous communication techniques.
- Deployment servers, external configuration, and containers are all tools to consider when coming up with an automated configuration plan.
- Service registration and discovery are pieces of your architecture that need to be in place early on. Often, custom solutions for service discovery are preferred.
- You should look towards 3rd-party monitoring tools such as New Relic or AWS Cloudwatch rather than building your own.