Eureka Server (using Steeltoe) revisited

The Eureka server is used as a registry for maintaining lists of services and their endpoints. It’s used a lot in the microservice world by way of a microservice registering it’s existence somewhere (in this case in Eureka). When a client (whether it’s another service or anything else for that matter) want to access a service it asks the registry for an instance, in this case we connect to the Eureka server and find the services instance(s) that are available for a specific application name and are ofcourse UP.

Installing and running Eureka Server

In a previous post Spring boot Eureka server we wrote a Java application to run a Eureka server. In this post we’re going to use Docker to host the server and then use Steeltoe with .NET to interact with the instance.

To get an image of Eureka server, let’s use the Steeltoe docker image (Spring and others exist, the Steeltoe image is not intended for production, but is fine for what we want to do)

docker pull steeltoeoss/eureka-server

Now run up the docker image using

docker run --publish 8761:8761 steeltoeoss/eureka-server

If all goes well, connect to the Spring Eureka dashboard using

http://locahost:8761

change localhost to the ip/host you’re running the Eureka server from, now you should now see the Spring Eureka web page.

Registering a .NET core client with Eureka

I’ve a post on this topic A .NET service registered with Eureka, but let’s go through the process again with the current version of Steeltoe (as the NuGet packages have changed somewhat).

  • Create an ASP.NET Core Web Application, as this will represent a REST service that we want to interact with. My project is called RegisterExample and is an API project.
  • Add the NuGet package Steeltoe.Discovery.ClientCore and Steeltoe.Discovery.Eureka
  • In Startup.cs within ConfigureServices add the following
    services.AddDiscoveryClient(Configuration);
    
  • Within the Configure method add the following
    app.UseDiscoveryClient();
    
  • Finally add the following to the appsettings.json file
    // Eureka info
      "eureka": {
        "client": {
          "serviceUrl": "http://localhost:8761/eureka/",
          "shouldFetchRegistry": "false",
          "shouldRegisterWithEureka": true,
          "validateCertificates": false
        },
        "instance": {
          "appName": "weatherapi",
          "port": "8080",
          "ipAddress": "localhost",
          "preferIpAddress": true
        }
      }
    

We’re going to leave the API with the default weatherapi, hence the appName in the appsettings.

Notice we set the value for “shouldFetchRegistry” to false as this service will not be acting as a client to any other services. Obviously change this is you also need to discovery other services. “shouldRegisterWithEureka” is set to true as we want this service to automatically register itself with Eureka.

Now navigate to the URL of your Eureka server again (or refresh) and you should see a new Application. In my case I have an application with the name weatherapi. This name comes from our appsettings.json configuration application/name.

Info and Health

If you click on the instance link within the Eureka server dashboard, you will navigate to

https://localhost:5001/info

(or whatever ip/hostname and port your service is running on) you get a 404, so let’s fix that in our project.

Info, by default will display some basic information about the application, product version etc. However you can also add further custom information if you want, but example the git build SHA1 hash or just some general info.

  • Add NuGet package Steeltoe.Management.EndpointCore
  • In Startup.cs ConfigureServices, add the following
    services.AddSingleton<IInfoContributor, MyInfoContributor>();
    services.AddInfoActuator(Configuration);
    services.AddHealthActuator(Configuration);
    

    The first of these lines will add our implementation of an IInfoContributor to allow for custom info.

  • Still in Startup.cs, but now the method Configure, add the following to the UseEndpoints endpoint routes

    endpoints.Map<InfoEndpoint>();
    endpoints.Map<HealthEndpoint>();
    
  • Now we’ll create a simple implementation of and IInfoContributor which allows us to add our own info, so add the following class

    public class MyInfoContributor : IInfoContributor
    {
       public void Contribute(IInfoBuilder builder)
       {
          builder.WithInfo("MyInfo", new { SomeName = "Scooby Doo" });
       }
    }
    

Now when we run our service we hope to see our info data, however by default Steeltoe seems to set the info and health endpoint to /actuator/info and /actuator/health respectively. Eureka seems to expect /info. So go to the appsettings.json and add the following to the Instance section

"StatusPageUrlPath": "/actuator/info",
"HealthCheckUrlPath": "/actuator/health" 

Note: I’m not sure what I’m missing here and why the defaults don’t match up, but these configuration changes will tell the Eureka server (when we register our service with it) that it should use these paths for info and health.

Now, if you run the service again for /actuator/info you should see something like this

{"MyInfo":{"someName":"Scooby Doo"},
"applicationVersionInfo":{"ProductName":"RegisterExample",
"FileVersion":"1.0.0.0","ProductVersion":"1.0.0"},
"steeltoeVersionInfo":"ProductName":"Steeltoe.Management.Endpoint",
"FileVersion":"3.0.2.0","ProductVersion":
"3.0.2\u002B4089779c66d127f40325a3be9b613149b3b090f2"}}

and health something like

{"status":"UP","details":{"liveness":{},"diskSpace":{"total":4000769372160,
"free":3889734168576,"threshold":10485760,"status":"UP"},"eurekaServer":
{"remoteInstStatus":"UNKNOWN","fetchStatus":"Not fetching","heartbeat":
"Successful","heartbeatStatus":"UP","heartbeatTime":"2021-01-23T20:40:44",
"status":"UP","applications":"NONE"},"readiness":{}}}