When you're moving from a monolith running on physical hardware towards a Cloud-based Microservices Architecture, there are several challenges. In a monolith, all the functionalities you need to run your application are on the same server. So in an e-commerce site application for example, updating the Inventory after an Order has been made is just a local call inside the same host in the same language; but when you are moving to a more dynamic environment with Microservices, where servers can be moved from hosts dynamically, scale up or down in a number of instances, and new services are added dynamically, then you start requiring a way to register and route traffic to the right services. How can we address this? that's the topic for today. I'm Christian, you're watching A Dev' Story and today we're going to talk about Service Discovery. Server Discovery is the process of locating resources on a network. In our case, it would be applications or services. All forms of server discovery requires some type of Service Registry. A Service Registry is basically a database where you store the services and their associated locations. Let's look at one of the oldest examples that would be DNS or Domain Name Service. A DNS will keep a list of the IP addresses of a service and associate it with an alias that would be its name. When you go to an URL you can resolve that to an IP address where the service is located. The Service Registry is very important and it needs to be kept up to date. So when a service that is registered shuts down, it needs to be removed from the registry; if a new service starts up then it needs to be added to the registry; and if a service is having some issues like it's unhealthy then it also needs to be removed from the Service Registry. There are different ways to categorize Service Discovery: one is about WHERE is the Server Discovery happening and the other one is about HOW you update the Service Registry let's take a look at those. There are two places where Server Discovery can happen: one is on the Client Side and the other one is on the Server Side. Let's talk first about Client Side. Before we dive in I wanted to talk about an example: when you want to go to a specific site on the internet and you put your URL on the browser, your computer doesn't necessarily know where this website is located so it will ask a DNS service for the registry. In the DNS there will be a query where it will ask: "for this domain, what are the IP addresses where this service is located?". Then the IP addresses are returned, your computer decides one of these IP addresses and it will hit the service on that IP address. Then, when retrieving the information, the website will be rendered on your computer. This is basically Client-Side Service Discovery. In a more generic way, when a service A wants to talk to a service B, it needs to ask the Service Registry where is service B located, and when it gets the information it will call service B directly by itself. On the other hand, we have Server Side Service Discovery. In Server Side Service Discovery, when a service A wants to talk to a service B it will instead do so by going through a Proxy. This Proxy will ask the Service Registry where service B is located and then redirect the request to service B, so there's no direct communication between service A and service B There are different pros and cons of each of these approaches. On the Client-Side Service Discovery, the main benefit is that it's simpler to implement. You don't need to set up a proxy or any type of infrastructure in order to make it work. You just need a registry and your service asking that registry in order to get the address where B is located. On the con side it requires a specific implementation for each of the languages that you have your services running on. So, for example, if you have a service running in Java, another one in Node, and another one in Python, each of them will require an implementation of Client-Side Service Discovery in order to communicate between each other. Another drawback that the Client-Side Service Discovery has, is that there is more coupling between the services and the Service Registry, so any change on the Service Registry could affect the implementation in all of the services. On Server Side Service Discovery then the pros and cons are inverted. The main benefits of Server Side Service Discovery is that it is language agnostic: you don't need a specific implementation of Service Discovery on any of your services directly; and also you don't need to have a coupling between the services and the Service Registry. But the main drawback is that you need to set up an infrastructure to do this. Another way to categorize Service Discovery is by HOW is the Service Registry maintained. There are two ways. One is Self Registration. In Self Registration, every service is responsible for updating the Service Registry. So, for example, if a service is starting up, it will notify the Service Registry to be added; and if a service is shutting down, then it will notify also the Service Registry in order to be removed. It also happens if the service has any problems. On the other hand we have Third-party Registration. In Third-party Registration there is an external application, also called the Registrar, which is observing the status of the services and updating the Service Registry automatically. This application is typically one of these two: one is a Sidecar (which would be a process running parallel to your service that makes sure to communicate with the Service Registry and update it accordingly) or it could also be a Service Orchestration Engine like Kubernetes. When you are running your Microservices in a Container Orchestration Engine like Kubernetes, the infrastructure automatically provides a Virtual IP address and a DNS name for your application; it will automatically update the Service Registry for you whenever a service goes up or down or is having issues. You can also do Server Side Service Discovery and use the infrastructure to properly direct the calls for you. Each of these approaches have their own pros and cons. For Self Registration, the main benefit is that the service itself knows very fine-grained details about what is its current status, so it can notify the Service Registry at the best time possible. On the other hand, some of the drawbacks of Self-Registration are that, for example, if you have a service that is hanging or is not responding, it will not be able to update the Service Registry. So the Service Registry will be out of date. And similar to Client Side Service Discovery there is coupling with the Service Registry and you need to have an implementation for every language that you have Microservices written on. For Third-party Registration, the main benefit is that it is language agnostic: you don't need a specific implementation for every type of Microservices that you have. And also, since it's an external application checking on your service, even if your service is hanging or is not responding, this third party application can check the status and update the Service Registry for you. On the con side, it depends on a specific Third-party Registration system that you use. For example, using a sidecar the main con is that you need another layer of infrastructure to be set up. So every service that you run will have this additional process that will be running with it. And for the Infrastructure-driven Third-party Registration the main con is that it can only register the services that this infrastructure deploys so any service that is deployed outside of your orchestration engine won't be added to the service registry automatically. As we just saw there are different ways of doing Service Discovery and each of them have their own benefits and drawbacks. And we didn't even touch many deeper topics like performance. There are many open questions still like, for example: What happens if you deploy a service outside of your infrastructure, let's say a different cloud provider, and you want to route traffic between them? Or a specific instance of a service is having downgraded performance but other instances of the service are working fine: How to redirect traffic to that one? Or can we do a smart traffic routing to go to the closest instance of the service that you want to contact? Many of these problems can be solved with another layer of infrastructure often used in Microservices Architecture called a Service Mesh. But that's a topic for another video. Thanks for watching!