What is Ambassador Pattern?
Scenario
We have an image sharing service. It has 3 components: Activity feed service, Users service, and the Image Store service.
The ‘Activity Feed’ service talks to the ‘Users’ service to get a list of users the current user is following. It talks to the ‘Image Store’ service to get the images posted by the users from the list.
Requirement: Data localization
Now let’s say that Government of India passes a new rule that all the data of Indian users must be stored inside India only.
To support this requirement, we shard the database of our Image Store service to store all images uploaded by Indians in the Indian shard. We then deploy a Image store service on an Indian server so that the service and data are close to each other. We add a stateless load balancer to the ‘Image Store’ service to direct requests for any images uploaded by Indian users to the Indian shard.
We realize that there is a problem with our approach that is there is a lot of load on the stateless load balancer and if this load balancer is down no one can access the ‘Image Store’ service. One way we can solve this problem is by using the Ambassador pattern.
What is the Ambassador Pattern?
Ambassador pattern deploys a container in a pod along with the application container. This ambassador container sends network requests on behalf of the application container.
Data localization using Ambassador pattern
We can solve the data localization problem using Ambassador pattern. We can have a Image Store Ambassador Container that is deployed along with the main application container. To retrieve the images of the users, the application controller makes a request on localhost to the Image Store Ambassador Container.
The Ambassador container has the logic to route the request to the required shard and returns the response to the application controller as if it had processed the request.
This solution provides an additional benefit of reducing the load on the load balancer and not making the load balancer a single point of failure. Even if the Indian Shard was down we can still show images of Non-Indian users in the activity feed.
Advantages of using Ambassador pattern
- It helps in building modular, reusable containers.
- It makes it easier to build and maintain these ambassador containers.
- It makes it easier to add features such as circuit breaking, routing, etc to a legacy application.
- Features offloaded to the ambassador can be managed/updated independently of the application.
When to use Ambassador pattern
- We should use this when we need to build a common set of client connectivity features.
- Need to support cloud or cluster connectivity requirements in a legacy application that is difficult to modify.
- When we want to standardize and extend instrumentation.
When not to use Ambassador pattern
- When network latency is critical.
- When client connectivity features are consumed by a single language.
- When connectivity features cannot be generalized ex: retry logic.
Examples
Beta testing
We can use ambassador pattern for even beta testing. The logic to redirect the user requests to the production version or beta version can be handled outside the application container and inside the ambassador container. As per the application container, it is getting all the responses from a single source on the localhost.
Ambassador for external services
We can add features like circuit breaking for external services. The payment ambassador container will be responsible for the security and circuit breaking logic for communicating with the external payment service.
References
- https://docs.microsoft.com/en-us/azure/architecture/patterns/sidecar
- https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/