Table of Contents

Netflix Eureka discovery client

The Steeltoe Eureka discovery client allows an application to register and unregister itself with a Eureka server and provides querying for service instances registered by other applications.

After it is activated, the client begins to operate in the background, both registering and renewing service registrations, sending periodic heartbeats to the Eureka server, and also periodically fetching the service registry from the server.

Using Netflix Eureka discovery client

To use this discovery client, add a NuGet package reference to Steeltoe.Discovery.Eureka and initialize it from Program.cs.

var builder = WebApplication.CreateBuilder(args);

// Steeltoe: Add service discovery client for Eureka.
builder.Services.AddEurekaDiscoveryClient();

var app = builder.Build();

Configuration settings

To get the Steeltoe discovery client to properly communicate with the Eureka server, there are several sections you may need to configure. What you provide depends on whether you want your application to register the running app and/or whether it needs to query for other apps.

For a complete understanding of the effects of many of these settings, we recommend that you review the documentation on the Netflix Eureka Wiki. In most cases, unless you are confident that you understand the effects of changing the values from their defaults, we recommend that you use the defaults.

Tip

Since Steeltoe v4, most of these settings can be changed at runtime, and the Eureka server is updated accordingly.

General

The following table describes the configuration settings that control the behavior of the client. All of these settings must start with Eureka:Client:.

Key Description Default
Enabled Whether to enable the Eureka client true
ServiceUrl Comma-separated list of Eureka server endpoints http://localhost:8761/eureka/
AccessTokenUri URL at which to obtain OAuth2 access token, before connecting to the Eureka server
ClientId Client ID for obtaining an access token
ClientSecret Secret for obtaining an access token
Validate_Certificates Whether the client validates server certificates true
EurekaServer:ShouldGZipContent Whether to auto-decompress responses from the Eureka server true
EurekaServer:RetryCount Number of times to retry Eureka server requests 2
EurekaServer:ConnectTimeoutSeconds How long to wait (in seconds) before a connection to the Eureka server times out 5
EurekaServer:ProxyHost Proxy hostname used in contacting the Eureka server
EurekaServer:ProxyPort Proxy port number used in contacting the Eureka server
EurekaServer:ProxyUserName Proxy username used in contacting the Eureka server
EurekaServer:ProxyPassword Proxy password used in contacting the Eureka server
Health:Enabled Whether to activate an IHealthContributor that verifies connectivity to the Eureka server true

Registration

The configuration settings below pertain to registering the currently running app as a service instance in Eureka. All of these settings must start with Eureka:Client:.

Key Description Default
ShouldRegisterWithEureka Whether to register the running app as a service instance true
Health:CheckEnabled Whether to query ASP.NET health checks and IHealthContributors during registration and renewals, to determine the status of the running app to report back to Eureka (see Configuring health checks) true

Additionally, the table below lists the configuration settings that control how to register the instance. All of these settings must start with Eureka:Instance:.

Key Description Default
InstanceId Unique ID (within the scope of the app name) of the instance to be registered with Eureka computed
AppName Name of the application to be registered with Eureka computed
AppGroup Name of the application group to be registered with Eureka
MetadataMap Name/value pairs associated with the instance computed
HostName Hostname on which the instance is registered computed
IPAddress IP address on which the instance is registered computed
UseNetworkInterfaces Query the operating system for network interfaces to determine HostName and IPAddress false
PreferIPAddress Whether to register with IPAddress instead of HostName false
VipAddress Comma-separated list of VIP addresses for the instance computed
SecureVipAddress Comma-separated list of secure VIP addresses for the instance computed
Port Non-secure port number on which the instance should receive traffic computed
NonSecurePortEnabled Whether the non-secure port should be enabled 1 computed
SecurePort Secure port on which the instance should receive traffic computed
SecurePortEnabled Whether the secure port should be enabled 1 computed
RegistrationMethod How to register on Cloud Foundry; can be route, direct, or hostname 2
InstanceEnabledOnInit Whether the instance should take traffic as soon as it is registered 3 true
LeaseRenewalIntervalInSeconds How often (in seconds) the client sends heartbeats to Eureka to indicate that it is still alive 30
LeaseExpirationDurationInSeconds Time (in seconds) that the Eureka server waits after receiving the last heartbeat before it marks the instance as down 90
StatusPageUrlPath Relative path to the status page for the instance 4 /info
StatusPageUrl Absolute URL to the status page for the instance (overrides StatusPageUrlPath) computed
HomePageUrlPath Relative path to the home page URL for the instance /
HomePageUrl Absolute URL to the home page for the instance (overrides HomePageUrlPath) computed
HealthCheckUrlPath Relative path to the health check endpoint of the instance 4 /health
HealthCheckUrl Absolute URL for health checks of the instance (overrides HealthCheckUrlPath) computed
SecureHealthCheckUrl Secure absolute URL for health checks of the instance (overrides HealthCheckUrlPath) computed
AsgName AWS auto-scaling group name associated with the instance
DataCenterInfo Data center the instance is deployed to (Netflix, Amazon, or MyOwn) MyOwn

The values for Port and SecurePort, and whether they are enabled, are automatically determined from the ASP.NET address bindings. 1 See 8 ways to set the URLs for an ASP.NET Core app for how to influence them using environment variables.

It is also possible to use dynamic port bindings (by setting the port number to 0 in ASP.NET). In that case, Steeltoe adds a random number (outside the valid port range) to the InstanceId to make it unique. After the app has fully started, the assigned port numbers are updated in Eureka, but the InstanceId does not change.

Querying

The configuration settings that pertain to querying the Eureka registry for apps (used by the load balancers during service discovery) are shown in the following table. All of these settings must start with Eureka:Client:.

Key Description Default
ShouldFetchRegistry Whether to periodically fetch registry information from the Eureka server true
RegistryFetchIntervalSeconds How often (in seconds) to fetch registry information from the Eureka server 30
ShouldFilterOnlyUpInstances Whether to include only instances with UP status after fetching the list of applications true
ShouldDisableDelta Whether to fetch the full registry each time (true) or fetch only deltas (false) false
RegistryRefreshSingleVipAddress Whether to fetch registry information only for the specified VIP address false
Health:MonitoredApps Comma-separated list of applications in Eureka that this app depends on (see Configuring health contributors)

Configuring health contributors

The Steeltoe Eureka package provides two different health contributors that you can use to monitor Eureka server health.

The first one, EurekaServerHealthContributor, is used to determine and report the health of the connection to the Eureka servers. It looks at the status of the last good registry fetch and the last heartbeat attempt and uses that information to compute the health of the connection. This contributor is automatically activated, but can be turned off by setting Eureka:Client:Health:Enabled to false.

The second contributor that you can enable is the EurekaApplicationsHealthContributor. By default, this contributor is not enabled, so you must add it to the service container explicitly:

builder.Services.AddSingleton<IHealthContributor, EurekaApplicationsHealthContributor>();

You can use the EurekaApplicationsHealthContributor to report the health of a configurable list of registered services based on their status in the registry. For each service it is configured to monitor, it looks at all of the instances of that service and, if all of the instances are marked DOWN, it reports your app as being in bad health. You can configure the services that it monitors using the Eureka:Client:Health:MonitoredApps configuration setting.

Typically you would set this to a list of the names of external services your app depends on; include those which, if they become unavailable, would affect the operation of your app. If this setting is left empty, all apps in Eureka are monitored.

Configuring health checks

If Eureka:Client:ShouldRegisterWithEureka is set to true (the default), the Eureka discovery client sends periodic heartbeats to inform the Eureka server that the currently running app is reachable.

Unless specified otherwise, the client does not propagate the current health status of the application, as calculated from the ASP.NET health checks and active health contributors, to Eureka. Consequently, after successful registration, Eureka always announces that the application is in UP state. You can alter this behavior by enabling Eureka:Client:Health:CheckEnabled (false by default), which results in propagating health status to Eureka. As a result, other applications stop sending traffic to your app until the health checks and contributors report the status as UP.

If you require more control over the health checks, consider implementing your own IHealthCheckHandler.

Configuring multiple Eureka servers

You can specify a comma-separated list of Eureka server URLs that the client uses when registering or fetching the service registry. These servers should be part of a properly configured Eureka server cluster, and should be using peer-to-peer communications to keep in sync.

The Eureka client automatically fails over to the other nodes in the cluster. When a failed Eureka server node comes back up, the Eureka client automatically reconnects back to the server at some point.

Using metadata

Standard instance information (such as hostname, IP address, port numbers, status page, and health check endpoint) is associated with every service registration. These are published in the service registry and are used by clients to contact the services in a straightforward way.

You can add additional metadata to instance registrations using the configuration setting Eureka:Instance:MetadataMap. The key/value pairs you supply there are added to the service registration, and become accessible to remote clients.

When the metadata changes over time, depending on contextual information, it can be updated from code as well:

var appManager = app.Services.GetRequiredService<EurekaApplicationInfoManager>();
appManager.UpdateInstance(newStatus: null, newOverriddenStatus: null,
    newMetadata: new Dictionary<string, string?>(appManager.Instance.Metadata)
    {
        ["someNewKey"] = "someValue1",
        ["someExistingKey"] = "someValue2"
    });
Important

After metadata has been updated from code, later metadata changes in configuration are ignored.

In general, additional metadata does not change the behavior of applications, unless they are made aware of the meaning of the metadata.

Configuring mutual TLS

To use mutual TLS authentication in the communication with the Eureka server, add the path to your certificate file(s) to appsettings.json. For example:

"Certificates": {
  "Eureka": {
    "CertificateFilePath": "example.p12"
  }
}

or:

"Certificates": {
  "Eureka": {
    "CertificateFilePath": "example.crt",
    "PrivateKeyFilePath": "example.key"
  }
}
Note

To support certificate rotation, the configuration keys and the files on disk are automatically monitored for changes.

Tip

A single certificate can be shared with both Config Server and Eureka by using the key Certificates, instead of Certificates:Eureka.

Using custom HTTP headers

The communication with Eureka server uses the HttpClientFactory pattern, which makes it aware of DNS changes over time and enables it to tweak the handler pipeline. For more information, see the Microsoft documentation.

To send a custom HTTP header with every request, create a DelegatingHandler and add it to the pipeline.

builder.Services.AddEurekaDiscoveryClient();
builder.Services.AddTransient<ExtraRequestHeaderDelegatingHandler>();

builder.Services.Configure<HttpClientFactoryOptions>("Eureka", options =>
{
    options.HttpMessageHandlerBuilderActions.Add(handlerBuilder =>
        handlerBuilder.AdditionalHandlers.Add(
            handlerBuilder.Services.GetRequiredService<ExtraRequestHeadersDelegatingHandler>()));
});

public sealed class ExtraRequestHeaderDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Add("X-Example", "ExampleValue");
        return base.SendAsync(request, cancellationToken);
    }
}
Tip

To send an extra header to the OAuth2 endpoint, replace "Eureka" with "AccessTokenForEureka" in the preceding example.


  1. When both non-secure and secure ports are enabled, the secure port is preferred during service discovery.

  2. Specify direct to use container-to-container networking on Cloud Foundry. Specify hostname to force using HostName.

  3. When set to false, call EurekaApplicationInfoManager.UpdateInstance() after initialization to mark the instance as UP.

  4. Add a NuGet package reference to Steeltoe.Management.Endpoint to use its health and info actuator paths.