What is an Ambassador
Ramesh Rathnayake
CTO at Fcode Labs | Co-Founder | AI | Blockchain | Engineering | Digital Healthcare
Ambassador is a microservices architecture design pattern that provides a unified entry point for external requests to the underlying microservices. This pattern can be useful in shifting common client connectivity tasks such as routing, security, and resiliency patterns in a language agnostic way. It is frequently used to extend the networking capabilities of legacy applications or applications that are difficult to modify. The goal is to decouple clients from the underlying microservices, allowing for more flexible and scalable deployments and minimizing the impact of microservice changes on clients.
The usage of the Ambassador pattern can be characterized as follows:
On the other hand, the pattern may not be an ideal choice in the following cases:
Advantages
Let's explore some key benefits of this pattern!
Implementation of the Ambassador Pattern for Service Sharding
Imagine you have a ton of data that you want to store, but it's too much for just one machine to handle. That's where sharding comes into play. Sharding takes your storage layer and splits it up into multiple pieces, each hosted on a different machine. This way, you can distribute the load across multiple machines instead of relying on just one. In this section, what we're discussing is all about taking an existing service and adapting it to work with a sharded service. But just to be clear, we won't be covering how the sharded service was created in the first place, we're just focusing on how to work with it.
But here's the thing — how do you integrate this new sharded service with your existing code that talks to a single storage backend? And what about sharing configuration between different environments? This is where using an ambassador comes in handy. An ambassador provides a unified entry point for external requests to the underlying sharded service and takes care of tasks like routing, security, and resiliency. By using an ambassador, you can retrofit your existing code to talk to the sharded service and simplify the process of deploying it in different environments (Dev, QA, UAT, Prod).
The Ambassador pattern helps to integrate sharded services by providing a unified entry point and directing traffic to the appropriate shard, simplifying deployment while allowing for flexible and scalable deployments. It can be implemented on the client side or integrated into the sharded service itself.
When it comes to sharding, you have two options. You can either build all the sharding logic into the sharded service itself, complete with a stateless load balancer to direct traffic. This complicates the deployment of the sharded service, but eliminates the need for a client-side ambassador. Alternatively, you can use a single-node ambassador on the client side to route traffic to the relevant shard, making the client's deployment more complex but simplifying the sharded service's deployment. The decision you make will depend on factors such as your architecture and the code you're writing versus deploying. In this section, I'll go over how to use the single-node ambassador pattern for client-side sharding.
This can be done by using an ambassador container. This container holds all the routing logic that directs requests to the corresponding storage shard. As a result, your frontend or middleware application only connects to a single storage backend, giving the impression that it is running locally. However, what it's actually connecting to is a sharding ambassador proxy, which acts as an intermediary. It receives requests from your application, routes them to the appropriate storage shard, and then returns the response to your app.
By using the ambassador pattern with sharded services, a clear separation is created between the application container and the sharding ambassador proxy. The application container only needs to access the storage service, which it finds on localhost, while the sharding ambassador proxy is responsible for performing the necessary sharding, making it reusable among different applications. Furthermore, using an off-the-shelf open source implementation of the ambassador can greatly speed up the development of the overall distributed system.
领英推荐
A Guide to Service Brokering
Let's talk about the challenges of making an application portable across different environments, like a public cloud, physical datacenter, or private cloud. Have you ever heard of service discovery and configuration?
Essentially, this is the process of ensuring that an application's frontend can access the appropriate utility servers regardless of the environment. Suppose it requires accessing the appropriate MySQL database to store its data, regardless of the environment it's being run in. For example, in a public cloud environment, the MySQL service might be offered as a software-as-a-service, but in a private cloud, a new virtual machine or container running MySQL might need to be created.
That's why building a portable application requires the application to be able to find the appropriate MySQL service to connect to by introspecting its environment. This process is known as service discovery, and the system that performs this task is called a service broker.
Now, here's where the ambassador pattern comes in. It enables a system to separate the logic of the application container from the logic of the service broker ambassador. The application simply always connects to an instance of the service running on localhost (which is the ambassador), while it's the responsibility of the service broker ambassador to introspect its environment and broker the appropriate connection.
An example of service discovery and configuration in portable applications is connecting a frontend to a MySQL database in different environments (public cloud, datacenter, private cloud). The service broker facilitates this connection.
Maximizing Efficiency with an Ambassador for Experimentation and Request Splitting
The final application of the ambassador pattern discussed in this article is experimentation or request splitting.
In many production systems, it's important to be able to split requests and redirect some of them to a different version of the service. This is usually done to test new or beta versions of the software and determine if it's reliable or performs as well as the current version that's deployed.
Request splitting is a technique where a portion of all requests are redirected to a different implementation of a service, rather than being serviced by the main production service. This is mainly used for experimentation purposes. For example, you can test the reliability and performance of a beta version of a service by redirecting a portion of requests to it. Additionally, request splitting can also be used to tee or split traffic such that all traffic goes to both the production system and a newer, undeployed version. The responses from the production system are returned to the user, while the responses from the tee-d service are ignored. This is mainly used to simulate production load on the new version of the service without affecting the existing production users.
The ambassador pattern comes in handy in these situations because it allows you to separate the logic of the main service from the logic of the experimental service. Let's talk about how a request-splitting ambassador can work in conjunction with an application container. Essentially, the application container is connected to a service running on localhost, which is also the ambassador container that is responsible for receiving requests and acting as an intermediary. The ambassador will take the incoming requests and redirect a portion of them to a different service, usually a newer or experimental version. The remaining requests will go to the primary production service.
Now, when the production service responds, the ambassador container returns the response to the user as if it had performed the work itself. This distinction between the ambassador and the application container helps keep the code in each container clean and focused on specific tasks. Additionally, the modular design of the application makes it easy to reuse the request-splitting ambassador for different applications and settings, without having to make major modifications to the code.
The request split is a technique used in production systems where a fraction of all requests are redirected to a different version of the service for testing purposes. This helps to determine the reliability and performance of a new beta version without affecting existing users.
Conclusion
In conclusion, the ambassador design pattern is a powerful and flexible tool for addressing many of the challenges that come with microservice architecture. It offers advantages like modularity, maintainability, and ease of use. This design pattern is a great option to consider when building a microservice-based application, especially if you are looking to implement service sharding, service brokering, or request splitting. However, it's important to remember that like any other tool, the ambassador design pattern is not the perfect solution for every scenario. In some cases, other approaches might be more appropriate, so it's important to carefully evaluate your specific needs before choosing a solution. Nevertheless, the ambassador design pattern is a valuable option to keep in mind when developing a microservice-based application and will likely prove to be a valuable asset in your microservice toolkit.