Microservice Manifesto
To ensure our distributed architecture is successful, we must ensure we have a set of guidelines
that must be followed. Failure to do this will simply result in chaos and ultimate failure. What follows
is a list of things that all service developers must ensure is taken into consideration when building or
modifying any service.
1. Split code into smaller, more manageable components
- Many smaller teams can work on different components contributing to the overall application ecosystem
- Components can be built, tested and deployed independently to provide value much more quickly
- Each component should use domain driven design
- No component should have intimate knowledge of any other service
Benefits
- A distributed microservice architecture forces us to think in small, atomic services/features
- Each service lives in it's own source code repo and has it's own CI/CD pipelines
-
A single service has it's own concern. By following the "Separation of Concerns" principle will allow
for build agility using existing building blocks
2. Employ a standard communication protocol
- Ensure reliable, predictable and timely communication between components
- Allow other systems/components to easily participate in/extend the features of an application or ecosystem
Benefits
- Http and Json is widely accepted for REST Api services
- An enterprise messaging platform (Kafka) enables very fast, highly available inter-service communication
-
An enterprise messaging platform (Kafka) enables easy integration with monolithic applications. Further it can
enable the extension of a monolith by adding service features that respond to enterprise events
-
Message versioning (schemas) should be employed and validated to ensure message consistency
3. Enable simple adoption of new technology
- There should be a path for new development, both new and re-engineering of old components
- We should not be married to a language, framework or persistence mechanism
Benefits
- Services are separated into their own code repositories and built using the language
and data store most appropriate with the domain they are concerned with
- New services can be built using different languages and data stores with no impact to other services
4. Reduce runtime environment complexity
- Components should be quickly and easily deployable
- Components should "just run". No more "works on my machine"
Benefits
- Docker provides a build once, run anywhere approach to runtime environments
- Each service has it's own CI/CD pipeline and a Docker container can be built
and deployed within seconds of a code check-in
- The only change between environments are environment variables. The bits are the same!
- The service manages it's own data store and creates/updates the schema automatically using migrations
- Testing is greatly reduced!
5. Enfore data quality and consistency
- All data should be cleansed and verified prior to being persisted
- Data should be segmented by domain/service
- The type of data should determine the best mechanism for it's persistence
Benefits
- Data reliability must be a core value
- Data should be logically or physically partitioned by domain and owned by only one service
- Database migrations must be used to ensure automated updates of schema and data
- Historical and transactional data should be split
- Ability to restrict access to historical or transactional
- Tune transactional data differently than historical
6. Enforce high code quality as a core value
- Use test automation and code analysis to ensure code confidence is high
- Do not rely on manual testing!
Benefits
- CI/CD (Continuous integration/deployment) pipelines can automate tasks for us:
- Build code
- Deploy to Docker container
- Run unit, load, stress and e2e tests
- Perform code quality analysis (SonarQube/SonarCloud)
- Release docker container to an orchestration cluster (Kafka)
7. Ensure high availability and redundancy are core values
- Build components/applications to work with many instances of themselves
- Ensure fault tollerance and recovery
Benefits
- Kubernetes allows the scaling of services based on individual demands
- Kubernetes automatically manages the cluster and keeps it in a predefined state
- Kubernetes does health checks and will kill and recreate unhealthy services. It will also
ensure the desired number of services are always running
- Kubernetes supports no downtime updates