With the evolution in technology, the development of single application has also changed by dividing application to multiple applications. These multiple applications can be located at various geographical location & developed using different technologies. To communicate between these multiple (interconnected) applications is a challenging task due to its distributed nature.
The main intention of this blog is to specify the challenges faced due to distributed nature.
Consider an application that consists of multiple subsystems, UI part (a Web application), along with the web api and back-end micro services which communicates to multiple databases for all the required server-side operations and makes them fully functional for their operations.
All the sub systems are best suited to be deployed on various hosting platforms like on-premises or on cloud (Microsoft Azure / AWS). Due to distributed nature, additional failures issues like latency issues, bandwidth, network issues, transient issues, and security issues needs to be handled properly.
The Application should handle or recover from all these kinds of failures and continue to function. It is called resiliency.
Being a distributed application there are chances which may makes services/application not working and thus various precautions can be taken like:
- The client should not wait indefinitely for a response from service. The client should use timeout to avoid deadlock situation.
- Use patterns like
- Retries with exponential back off – The operation will succeed if failure is short or intermittent. Faults may be because of slow connection and service unavailability. In such scenarios, few retries or calls are necessary to avoid failure. Make sure that it may not result to denial of service. Wait for some time before first retry and then increase time exponentially for each retry.
- Use the Circuit Breaker pattern. The purpose of this pattern is different from retry pattern. When the faults are due to unanticipated events like service failure or service unavailability, application should handle the failure accordingly. This can be achieved by comparing number of failed request with configured limit.
- Always use combination of retries and circuit breaker pattern to avoid transient failures.
- All kind of failures should be logged as a part of exception handling.
- Despite all these, when request fails, the client application should implement fallback logic like returning cached data, a default value or custom error page.
- To avoid service overloading, service API and resources should be exposed to certain users and clients. This can be achieved using authentication mechanism.
- Secure way of communication between client application and services requires credentials, tokens, passwords, and other types of confidential information—called as secrets. Secrets needs to be store safe. The most secure way of storing secrets is Azure Key Vault, which provides a secure, central location for storing keys and secrets. Make sure to encrypt confidential information while passing from client to service or vice versa.
- The changes in service may be because of business requirement change, data change or operation change. Versioning ensures that the change in service does not impact already existing functionality. It ensures backward compatibility. All clients can call specific version of resource without changing any client-side code.
Versioning can be implemented using
- URI Versioning
- Query string versioning
- Header versioning
- Service or web api should expose methods or operations as asynchronous if it needs to communicate with external source, multiple databases or multiple services.
- Needs to have secured communication between client application and Web API in distributed environment like SSL security.
- Changes in service operation need to be updated in new version of service. The different update options (deployment strategies) are-
- Rolling Update- The update is performed in stages. Old and new version of service exists simultaneously, so there is less downtime.
- Delete & Upload- Stop the service, delete the deployment & deploy the new version service. Downtime is inevitable in this case of deployment.
- Blue Green deployment- Additional hardware is required in this case of deployment, so cost is high but downtime is zero. While in one environment, older version of services run and is called blue in the other environment, new version of services run and is called Green.
Besides all these factors distributed application provided us a suitable way to leverage the best services from different platforms to enhance the working of application.