Service Registration Pattern With Golang and Eureka
Learn how to set up service registration for your microservices instances with Eureka in this tutorial.
Join the DZone community and get the full member experience.
Join For FreeWhen we talk about microservices architecture, we think of multiple small services working together. Each of which is independent and could be deployed separately.
In most cases, the number of service instances and their locations changes dynamically. Virtual machines and containers are usually assigned a dynamic IP address. Also, in the case of auto-scaling, the underlying platform adjusts the number of instances based on load and other factors.
This raises a problem: how do clients of a service and/or routers know about the available instances of a service (host and port)?
The solution to this problem is to implement a service registry, which is a database of services, their instances, and their locations. Instances are registered with the registry on start-up and de-registered on shutdown. Clients and/or routers query the registry to find the available instances of a service.
There are multiple implementations available in both the commercial and open-source space. To name a few:
Most available service registry implementations provide an interface (most commonly a REST API) to register and query for instances. The lifecycle of an instance can be depicted these three steps:
Register: In the first step, the microservice instance needs to register itself with the service registry
Heartbeat: The instances send their heartbeats at predefined intervals. If the registry does not receive the heartbeat of an instance for a particular amount of time, then it marks the instance as down and removes the instance based on configurations.
Deregister/Down: If the instance is going to be down or is being shut down, then the instance needs to deregister itself from the service registry. Once the registry marks an instance as "down," it stops all the traffic to that instance.
Most of the registries offer plug-and-play client libraries, cutting the effort required to implement the whole process. Netflix Eureka is an open-source service registry which offers client libraries for Java. It works flawlessly with Spring and is widely used.
One of the major advantages of microservices is that you are not bound to a particular programming language or technology. As we know, Eureka also offers a REST interface for interaction. Let us try to implement a service in Golang that registers itself with a Netflix Eureka registry. To achieve this, we need to implement the below flow:
Let us try to register an application with name "MY_AWSOME_GO_MS ". I assume that you have Eureka registry running on your local machine.
Input: The details of the registry need to be supplied as input. In our case, we will be reading from environment variables.
REGISTRY_TYPE: this shall contain the value "NETFLIX_EUREKA."
REGISTRY_URL: We will be running the Netflix Eureka Registry locally on port 8761, so the value will be "http://localhost:8761/eureka/apps/"
REGISTRY_USER: If we have secured our registry, the username will be used for authentication.
REGISTRY_PASSWORD: Password for the user.
While starting up the instance, register the instance by calling the URL "http://localhost:8761/eureka/apps/{SERVICE_NAME}." In our case, the URL will be "http://localhost:8761/eureka/apps/MY_AWSOME_GO_MS." This shall be a POST request with the body as follows:
{
"instance": {
"hostName": "MY_HOSTNAME", #hostname of my machine
"app": "org.github.hellosatish.microservicepattern.awesomeproject",
"vipAddress": "org.github.hellosatish.microservicepattern.awesomeproject",
"secureVipAddress": "org.github.hellosatish.microservicepattern.awesomeproject"
"ipAddr": "10.0.0.10",
"status": "STARTING",
"port": {"$": "8080", "@enabled": "true"},
"securePort": {"$": "8443", "@enabled": "true"},
"healthCheckUrl": "http://MY_HOSTNAME:8080/healthcheck",
"statusPageUrl": "http://MY_HOSTNAME:8080/status",
"homePageUrl": "http://MY_HOSTNAME:8080",
"dataCenterInfo": {
"@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
"name": "MyOwn"
},
}
}
3. Once your application is ready to serve a request, we need to update the instance status to UP. This will be achieved by again sending an HTTP POST request to the registry. The request body will be same, except the status will be UP this time.
4. Eureka needs to receive a heartbeat from the instance in every 30 seconds. The heartbeat is sent via a "HTTP PUT" call to the URL "http://localhost:8761/eureka/apps/{APP_NAME}/{INSTANCE_ID}". By default, the instance ID is the hostname of the application, so our URL will be "http://localhost:8761/eureka/apps/MY_AWSOME_GO_MS/MY_HOSTNAME."
5. If the instance needs to shut down, then we need to again update the status to DOWN. The request body is the same as we used to register with the status STARTING or UP but the statusfield has value DOWN.
If Eureka does not receive a heartbeat for 90 seconds, it automatically removes the instance from the registry. Let's stop our application and after 90 seconds, we can see that the instance has been removed from the registry.
You can find the working code and compiled binaries in this GitHub repository.
Opinions expressed by DZone contributors are their own.
Comments