Microservices antipatterns

Takeaways from microservice antipatterns:

  1. Overzeal­ous Services – don’t go straight into microservices, (fol­low­ing the hype per­haps?) rather than start­ing with the sim­plest thing possible. Instead, you should start by doing the sim­plest thing pos­si­ble, iden­tify the hotspots as they become appar­ent and then extract them into microservices. Start with monolith.
  2. Schemas Every­where – avoid having a shared data­base between dif­fer­ent ser­vices. This cre­ates tight cou­pling between the ser­vices and means you can’t deploy the microservices inde­pen­dently if it breaks the shared schema. Any schema updates will force you to update other microservices too. Instead, every ser­vice should have its own data­base, and when you want data from another ser­vice you go through its API rather than reach­ing into its data­base and help yourself. Use semantic versioning.
  3. Spiky Load between Services – You often get spiky traf­fic between ser­vices, and a com­mon solu­tion is to amor­tise the load by using queues between the services. Use rabbitmq.com, redis, etc.
  4. Hard­coded IPs and Ports – One solu­tion would be to use a dis­cov­ery ser­vice such as con­sul or etcd, and there’s also Netflix’s eureka. Another solu­tion is to use a cen­tralised router. Both solu­tions require reg­is­tra­tion and dereg­is­tra­tion, and both require high avail­abil­ity and scalability.
  5. Dog­piles – If one of your ser­vices is under load or mal­func­tion­ing, and all your other ser­vices keep retry­ing their failed calls, then the prob­lem would be com­pounded and mag­ni­fied by the addi­tional load from these retries. The solu­tion here is to have expo­nen­tial back­off and imple­ment the cir­cuit breaker pattern. Many libraries such as Netflix’s Hys­trix and Polly for .Net are available. You can even use the ser­vice dis­cov­ery layer to help prop­a­gate the mes­sage to all your ser­vices that a cir­cuit has been tripped (i.e. a ser­vice is struggling).
  6. Debug­ging Hell – Debug­ging is always a huge issue in micro-service archi­tec­tures. E.g., a nested ser­vice call fails and you can’t cor­re­late it back to a request com­ing from the user. One solu­tion is to use cor­re­la­tion IDs. When a request comes in, you assign the request with a cor­re­la­tion ID and pass it on to other ser­vices in the HTTP request header. Every ser­vice would do the same and pass the cor­re­la­tion ID it receives in the incom­ing HTTP header in any out-going requests. When­ever you log a mes­sage, be sure to include this cor­re­la­tion ID in the log line.
  7. Miss­ing Mock Servers – When you have a ser­vice that other teams depend on, each of these teams would have to mock and stub your ser­vice in order to test their own services. A good step in the right direc­tion is for you to own a mock ser­vice and pro­vide it to con­sumers.  You can take it a step fur­ther, by build­ing the mock ser­vice into the client so you don’t even have to main­tain a mock ser­vice any­more. Use Any­point Plat­form or Swagger.
  8. Fly­ing Blind – There are more than a hand­ful of tools avail­able in this space. There are com­mer­cial tools (some with free tiers) such as NewRelic and Stack­Driver (now inte­grated into Google AppEn­gin), AWS also offers Cloud­Watch as part of its ecosys­tem. In the open source space, Net­flix has been lead­ing the way with Hys­trix and  some­thing even more excit­ing.

Links: