Wednesday, August 28, 2019

Microservices Best Practices


  • Instead of a monorepo, structure individual repositories per microservice. This allows for granular access control (like contributors, reviewers, viewers, etc) and also allows for individual microservices build versioning.
  • Serverless deployments like AWS Lambda, Google Cloud Functions can fit well as part of microservices architecture, for small ad-hoc functions.
  • The microservices should employ loosely-coupled messaging communication style. As per the ‘Reactive Systems’ manifesto, the services should be ‘message-driven’, which ensures loose-coupling, isolation and location transparency. Apache Kafka, AWS Kinesis can serve the purpose of asynchronous messaging.
  • Architect group of microservies to be deployed as containers on a single host(cluster). Microservices should be deployed in containers like docker. There are multiple strategies like ‘multiple services per host’, ‘single service per host’. In order to leverage the benefits of containerization (multiple containers per host) and also to address scalability (and cost) concerns, architect the services as a group of services which can be deployed in single host (a.k.a cluster). There will be multiple clusters with each cluster having group of microservices.
  • Evaluate the technology(ies) to be used in each microservice separately. The requirements from the microservice should drive the choice of technologies, e.g. concurrency, serverless deployment, subdomain requirements, etc.
  • Use a microservices chassis framework like Spring Boot/Dropwizard (Java) or Go Kit, Micro, Gizmo (Go) for microservices cross-cutting concerns like logging, health check, distributed tracing, metrics, etc.
  • With advancement in UI frameworks like Angular, React, etc, ‘client-side UI composition’ should be utilized which composes the UI fragments rendered from multiple microservices, rather than ‘server-side page fragment composition’.
  • The observability of microservices is a critical aspect. Ensure implementing distributed tracing, application metrics, log aggregation. Open Zipkin, Dapper, Jaeger can be used for distributed tracing. Micrometer, Prometheus can be used for application metrics. Log aggregation can be done via AWS Cloudwatch, Splunk, etc.
  • Service component tests should be implemented with test doubles for the associated services. Framework like WireMock can be used for this purpose.
  • From the ‘Reliability’ perspective, implement Circuit Breaker pattern for failing requests beyond a threshold for a microservice. Netflix Hystrix can be used for this purpose.
  • Try to avoid API versioning; keep the APIs backward compatible. If API versioning is required, evaluate URL, request parameter, request header strategies for API versioning.
  • Evaluate cloud native architecture as next stage of microservices architecture which gives advantages like using sidecar proxies and service meshes.