Table of Contents

Netflix Eureka

The Eureka client implementation lets applications register services with a Eureka server and discover services registered by other applications. This Steeltoe client is an implementation of the 1.0 version of the Netflix Eureka client.

The Eureka client implementation supports the following .NET application types:

  • ASP.NET (MVC, WebForm, WebAPI, WCF)
  • ASP.NET Core
  • Console apps (.NET Framework and .NET Core)

Here are several Steeltoe sample applications when looking for help in understanding how to use this client:

  • AspDotNet4/Fortune-Teller-Service4: Same as the Quick Start next but built for ASP.NET 4.x and using the Autofac IOC container.
  • AspDotNet4/Fortune-Teller-UI4: Same as the Quick Start next but built for ASP.NET 4.x and using the Autofac IOC container
  • MusicStore: A sample application showing how to use all of the Steeltoe components together in a ASP.NET Core application. This is a microservices-based application built from the ASP.NET Core MusicStore reference app provided by Microsoft.
  • FreddysBBQ: A polyglot microservices-based sample application showing interoperability between Java and .NET on Cloud Foundry. It is secured with OAuth2 Security Services and using Spring Cloud Services.

Usage

You should know how the new .NET Configuration service works before starting to use the client. A basic understanding of the ConfigurationBuilder and how to add providers to the builder is necessary in order to configure the client.

You should also know how the ASP.NET Core Startup class is used in configuring the application services and the middleware used in the app. Pay particular attention to the usage of the Configure() and ConfigureServices() methods.

You should also have a good understanding of the Spring Cloud Eureka Server.

In order to use the Steeltoe Discovery client, you need to do the following:

  • Add appropriate NuGet package reference to your project.
  • Configure the settings the Discovery client will use to register services in the service registry.
  • Configure the settings the Discovery client will use to discover services in the service registry.
  • Add and Use the Discovery client service in the application.
  • Use an injected IDiscoveryClient to lookup services.

NOTE: Most of the example code in the following sections is based on using Discovery in a ASP.NET Core application. If you are developing a ASP.NET 4.x application or a console-based app, see the other samples for example code you can use.

Eureka Settings

To get the Steeltoe Discovery client to properly communicate with the Eureka server, you need to provide a few configuration settings to the client.

What you provide depends on whether you want your application to register a service and whether it also needs to discover services with which to communicate.

General settings that control the behavior of the client are found under the prefix with a key of eureka:client. Settings that affect registering services are found under the eureka:instance prefix.

The following table describes the settings that control the overall behavior of the client:

All of these settings should start with eureka:client:

Key Description Default
shouldRegisterWithEureka Enable or disable registering as a service true
shouldFetchRegistry Enable or disable discovering services true
shouldGZipContent Enable or disable GZip usage between client and Eureka server true
serviceUrl Comma delimited list of Eureka server endpoints http://localhost:8761/eureka
validateCertificates Enable or disable certificate validation true
registryFetchIntervalSeconds Service fetch interval 30s
shouldFilterOnlyUpInstances Whether to fetch only UP instances true
instanceInfoReplicationIntervalSeconds How often to replicate instance changes 40s
shouldDisableDelta Whether to disable fetching of delta and, instead, get the full registry false
registryRefreshSingleVipAddress Whether to be interested in only the registry information for a single VIP none
shouldOnDemandUpdateStatusChange Whether status updates are trigger on-demand register/update true
accessTokenUri URI to use to obtain OAuth2 access token none
clientSecret Secret to use to obtain OAuth2 access token none
clientId Client ID to use to obtain OAuth2 access token none
cacheTTL Time in seconds local cache entries are valid 15
eurekaServer:proxyHost Proxy host to Eureka Server none
eurekaServer:proxyPort Proxy port to Eureka Server none
eurekaServer:proxyUserName Proxy user name to Eureka Server none
eurekaServer:proxyPassword Proxy password to Eureka Server none
eurekaServer:shouldGZipContent Whether to compress content true
eurekaServer:connectTimeoutSeconds Connection timeout 5s
eurekaServer:retryCount Number of times to retry Eureka Server requests 3
health:enabled Enable or disable management health contributor true
health:checkEnabled Enable or disable Eureka health check handler true
health:monitoredApps List apps the management health contributor monitors All apps in registry

NOTE: Some settings above affect registering as a service as well.

The following table describes the settings you can use to configure the behavior of the client as it relates to registering services:

Key Description Default
appName Name of the application to be registered with Eureka 'spring:application:name' or 'unknown'
port Port on which the instance is registered 80
hostName Address on which the instance is registered computed
instanceId Unique ID (within the scope of the appName) of the instance registered with Eureka computed
appGroupName Name of the application group to be registered with Eureka none
instanceEnabledOnInit Whether the instance should take traffic as soon as it is registered false
securePort Secure port on which the instance should receive traffic 443
nonSecurePortEnabled Non-secure port enabled for traffic true
securePortEnabled Secure port enabled for traffic false
leaseRenewalIntervalInSeconds How often client needs to send heartbeats 30s
leaseExpirationDurationInSeconds Time the Eureka server waits before removing instance 90s
vipAddress Virtual host name hostName + port
secureVipAddress Secure virtual host name hostName + securePort
metadataMap Name/value pairs associated with the instance none
statusPageUrlPath Relative status page path for this instance /Status
statusPageUrl Absolute status page for this instance computed
homePageUrlPath /
homePageUrl Absolute home page for this instance computed
healthCheckUrlPath /healthcheck
healthCheckUrl Absolute health check page for this instance computed
secureHealthCheckUrl Secured absolute health check page for this instance computed
ipAddress IP address to register computed
preferIpAddress Whether to register by using IpAddress instead of hostname false
registrationMethod How to register service on Cloud Foundry. Can be route, direct, or hostname route

All of the settings in the preceding table should start with eureka:instance:.

You should register by using the direct setting mentioned earlier when you want to use container-to-container networking on Cloud Foundry. You should use the hostname setting on Cloud Foundry when you want the registration to use whatever value is configured or computed as eureka:instance:hostName.

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 you understand the effects of changing the values from their defaults, we recommend that you use the defaults.

Settings to Fetch Registry

The following example shows the clients settings in JSON that are necessary to cause the client to fetch the service registry from the server at an address of http://localhost:8761/eureka/:

{
"spring": {
    "application": {
      "name": "fortuneUI"
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldRegisterWithEureka": false
    }
  }
  ...
}

The eureka:client:shouldRegisterWithEureka instructs the client to NOT register any services in the registry, as the application does not offer any services (that is, it only wants to discover).

NOTE: If you use self-signed certificates on Cloud Foundry, you might run into SSL certificate validation issues when pushing apps. A quick way to work around this is to disable certificate validation until a proper solution can be put in place.

Settings to Register Services

The following example shows the clients settings in JSON that are necessary to cause the client to register a service named fortuneService with a Eureka Server at an address of http://localhost:8761/eureka/:

{
 "spring": {
    "application": {
      "name":  "fortuneService"
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldFetchRegistry": false
    },
    "instance": {
      "port": 5000
    }
  }
  ...
}

The eureka:instance:port setting is the port on which the service is registered. The hostName portion is determined automatically at runtime. The eureka:client:shouldFetchRegistry setting instructs the client NOT to fetch the registry as the app does not need to discover services. It only wants to register a service. The default for the shouldFetchRegistry setting is true.

The samples and most templates are already set up to read from appsettings.json.

Bind to Cloud Foundry

When you want to use a Eureka Server on Cloud Foundry and you have installed Spring Cloud Services, you can create and bind a instance of the server to the application by using the Cloud Foundry CLI, as follows:

# Create eureka server instance named `myDiscoveryService`
cf create-service p-service-registry standard myDiscoveryService

# Wait for service to become ready
cf services

# Bind the service to `myApp`
cf bind-service myApp myDiscoveryService

# Restage the app to pick up change
cf restage myApp

For more information on using the Eureka Server on Cloud Foundry, see the Spring Cloud Services documentation.

Once the service is bound to your application, the connection properties are available in VCAP_SERVICES.

Enable Logging

Sometimes, it is desirable to turn on debug logging in the Eureka client. To do that simply add the following to your appsettings.json:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Information",
      "Steeltoe":  "Debug"
    }
  }
}

Configuring Health Contributors

The Eureka package provides two different Steeltoe Management Health contributors that can be used 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 last good registry fetch and/or the last heartbeat attempt and using that information computes the health of the connection.

If you use the AddDiscoveryClient() extension method and you have configured Eureka as your service discovery choice this contributor is automatically added to the container and will automatically picked up an used.

The contributor is enabled by default, but can be disabled by setting eureka:client:health:enabled=false.

The second contributor that you can enable is the EurekaApplicationsHealthContributor. This contributor is not enabled by default, so you must add it to the service container yourself:

    services.AddSingleton<IHealthContributor, EurekaApplicationsHealthContributor>();

The EurekaApplicationsHealthContributor can be used to report the health of a configurable list of registered services based on the status of the service 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, then the service will be reported 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 the list of external service names the app is dependent on and if unavailable would impact the operation of the app.

Configuring Health Checks

By default, Eureka uses the client heartbeat to determine if a client is up. Unless specified otherwise, the Eureka client does not propagate the current health status of the application as calculated by the health contributors configured for the application. Consequently, after successful registration, Eureka always announces that the application is in 'UP' state. This behavior can be altered by enabling Eureka health checks, which results in propagating application status to Eureka. As a consequence, every other application does not send traffic to applications in states other then 'UP'.

To enable this behavior you need to add the IHealthCheckHandler to your service container. The handler is not added to the container by default.

    services.AddSingleton<IHealthCheckHandler, ScopedEurekaHealthCheckHandler>();

You can enable or disable the handler by using the following eureka:client:health:checkEnabled configuration settings. It is enabled by default.

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

Configuring Multiple ServiceUrls

You can specify a comma delimited list of Eureka server URLs the client will use when registering or fetching the service registry. Those servers listed 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 will automatically failover to the other nodes in the cluster. When a failed Eureka server node comes back up, the Eureka client will automatically reconnect back to the server at some point.

Configuring Metadata

It is worth spending a bit of time understanding how the Eureka metadata works so you can use it in a way that makes sense in your application.

There is standard metadata information such as hostname, IP address, port numbers, status page, and health check endpoint that 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.

Additional metadata can be added to instance registrations using the configuration setting eureka:instance:metadataMap. The metadata you supply using this configuration is added to the service registration and becomes accessible in remote clients.

In general, additional metadata does not change the behavior of the client, unless the client is made aware of the meaning of the metadata.