A microservice architecture has its set of advantages, and we’ve also talked a bit about when it is the best choice for your business. What’s next is understanding how best to create one for your enterprise applications. While the exact architecture will vary, there are certain best practices that help design an effective and optimal microservice architecture.
Domain Driven Design
The entire point of microservices is to break up a unified architecture into smaller, more manageable parts. But this break up has to be done in a manner that makes sense to all stakeholders.
A few common approaches to defining the scope of individual microservices:
Create microservices that correspond to the different operational teams that exist in the application development process. For example: one team could be working on user authentication, another on data collection and each of them should be responsible for creating a set of microservices that achieve that particular task.
Create microservices corresponding to specific functionalities. For example: an analytics application can have a chatbot functionality, a visual dashboard, a data analytics functionality and more. Each of these can be created as separate pieces that converse via APIs.
The idea is to create an independent set of services that offer a focussed value add. The challenge is to avoid overstuffing too many functionalities into one microservice. It’s usually advised to keep the code simple enough to be easily re-deployed when required.
The independence of microservices is the key to their effectiveness. The fact that they are loosely coupled and work without complex interdependence makes sure that entire applications don’t go down due to single point failures. Hence, there are a few key areas where independence has to be ensured:
Independent teams: Each microservice should ideally have its own dedicated team that comprises of a product manager and DevOps team. One team taking each service from development to deployment helps in frequent releases and maximum uptime.
Automate for independent deployment: Automating build and release cycles, and making sure each microservice can be deployed independent of others is critical for well designed applications. That way they can be up and running on any environment.
Separate storage: Each microservice should own its specific database, and any other services requiring that data should access it through APIs only. Sharing databases might look like a convenient option in the short run. But as microservices scale, this sharing causes them to become coupled with each other, defeating the purpose.
Isolate failure: To ensure that applications continue to run even as one service fails, microservice architecture needs to isolate failure. A common way to do that is to establish circuit breakers in the application. When a service fails beyond a set number of times, the circuit breaker trips and immediately fails all requests to that service for a given time period. The functionality offered by that service remains unavailable for that time period, even as the rest of the application keeps working. After the timeout, the circuit breaker allows a few requests to pass, and if successful reverts back to normal operation.
Similar to this, other design patterns such as asynchronous communication, and event-driven architecture can be used for failure isolation.
Immutable infrastructure divides services into data and ‘everything else’, and the ‘everything else’ part is replaced at each release. However, a new version of the microservice is created rather than updating the current version right away. The new version is tested and fine tuned while the older version is the one being used by the application. Only when the new version is stable should it be merged with the previous one.
As organizations rely more on microservices architecture, with different teams working on different services, processes and practices can start to vary across teams. Each team could start doing development, deployment, and error handling differently. This could lead to a lot of code being repeated by different teams, impacting efficiency and turnaround times.
Hence, it’s advisable to create organization-wide standards that teams can adhere to. Processes for microservice creation and deployment, as well as their corresponding APIs should be well documented. This also allows different teams to understand other microservice APIs being used, and how to best use them.
Best practices shared, our next blog will concentrate on event sourcing microservices and handling deployment with docker.
Srijan is assisting enterprises in moderninzing applications with microservices architecture, primarily leveraging Docker and Kubernetes.
Looking to drive your digital transformation with microservices? Just drop us a line and our expert team will be in touch.