Microservices

  • Each microservice should be developed and deployed independently.
  • There should be no dependency between your microservice, or any other microservice or application, if possible.
  • Your microservice should be deployable all by itself.
  • Each microservice should be its own solution/codebase.
  • Each microservice should have its own data sources. Now, while this is the accepted best practice, it doesn't always hold up. If your project is a green-field project, perhaps you will get lucky, otherwise, we usually have data sources developed and in use long before we get to this project. Although a best practice, it is often not applicable for various reasons.
  • Each microservice should communicate with other microservices via an asynchronous, event-driven, message-based approach to reduce inter-service dependencies.
  • The change of one microservice should not break another. This sometimes does happen, but we should try to minimize such an occurrence.
  • Each microservice should be small enough to serve a specific business purpose, yet big enough to minimize any inter-service dependencies.
  • Never wait to return from processing a message. Spawn a background working process.
  • Always use the Hollywood Principle. What does that mean? Don't call us, we'll call you! In microservice speak, that means don't poll for information, just wait for messages to arrive!
  • Use circuit breaker patterns wherever possible. A circuit-breaker prevents requests that are known to fail (usually to a previous failure attempt) from being attempted. If there are failures, set a flag and stop trying for a designated period. Once that time has expired, reset the flag and try again. The status of your circuit breaker should be reported to the health monitoring microservice. I also recommend what is known as exponential backoff for your circuit-breaker. What this means is that each subsequent request for something that previously failed is spread out a bit longer than the previous request. This gives the error condition more time to heal itself. If the first retry was done after 10 seconds, the second could be done after 15, the third after 20, and so on.
  • Message sending and receive should be done asynchronously.
  • User correlation IDs. The chain of custody in a microservice is so very important. Being able to trace a complete event history from start to finish is invaluable, and passing a chain of custody identifier (correlation ID) is the way to handle this. When you are trying to resurrect the complete path of a request or event, this will help you to do so.
  • Your microservice should be stateless if running behind a load balancer. Having a state-based microservice can be very beneficial if done correctly. Just remember that this could have a negative impact if running behind a load balancer.
  • Think carefully about how your microservice will function if one or more microservices, services, or applications are down or encounter errors.
  • Each microservice should have automated monitoring and alerting in case of problems. Agree on what it means for a microservice to be in an unhealthy state, what an alert will do, mean, and provide, and implement accordingly.
  • Always have a second-level microservice designed for nothing but health-monitoring.
  • Understand how decentralized interactions benefit you. Each microservice must take full responsibility for its role in the greater ecosystem. Each microservice must listen for events and messages, complete all work as quickly as possible, make sure that a retry mechanism exists for handling failures, and send result messages quickly if required. Doing so will give us loose coupling and high cohesion, resulting in greater autonomy for each microservice and your ecosystem. This is another reason to have a health monitor microservice: so as to be able to track statuses, events, and so on.
  • Strive for separation of concerns whenever possible.
  • Strive for idempotency. Jobs or tasks should be able to be retried multiple times.
  • Strive for eventual consistency. In short, this means that if no new request has been made to the microservice, once a request is made, it will return the last updated data or item.
  • Use asynchronous workers whenever possible. Why?
    • This speeds up the request path as requests are non-blocking.
    • This spreads the load to allow for easier scalability.
    • This reduces errors since failed workers can be retried behind the scenes.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset