This project provides Netflix OSS integrations for Spring Boot apps through autoconfigurationand binding to the Spring Environment and other Spring programming model idioms. With a fewsimple annotations you can quickly enable and configure the common patterns inside yourapplication and build large distributed systems with battle-tested Netflix components. Thepatterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix),Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
Service Discovery is one of the key tenets of a microservice based architecture. Trying to hand configure each client or some form of convention can be very difficult to do and can be very brittle. Eureka is the Netflix Service Discovery Server and Client. The server can be configured and deployed to be highly available, with each server replicating state about the registered services to the others.
To include Eureka Client in your project use the starter with group org.springframework.cloudand artifact id spring-cloud-starter-netflix-eureka-client. See the Spring Cloud Project pagefor details on setting up your build system with the current Spring Cloud Release Train.
When a client registers with Eureka, it provides meta-data about itselfsuch as host and port, health indicator URL, home page etc. Eurekareceives heartbeat messages from each instance belonging to a service.If the heartbeat fails over a configurable timetable, the instance isnormally removed from the registry.
(i.e. utterly normal Spring Boot app). By having spring-cloud-starter-netflix-eureka-client on the classpath your application will automatically register with the Eureka Server. Configuration is required tolocate the Eureka server. Example:
Having spring-cloud-starter-netflix-eureka-client on the classpathmakes the app into both a Eureka "instance"(i.e. it registers itself) and a "client" (i.e. it can query theregistry to locate other services). The instance behaviour is drivenby eureka.instance.* configuration keys, but the defaults will befine if you ensure that your application has aspring.application.name (this is the default for the Eureka serviceID, or VIP).
HTTP basic authentication will be automatically added to your eurekaclient if one of the eureka.client.serviceUrl.defaultZone URLs hascredentials embedded in it (curl style, like :password@localhost:8761/eureka). For more complex needsyou can create a @Bean of type DiscoveryClientOptionalArgs andinject ClientFilter instances into it, all of which will be appliedto the calls from the client to the server.
The status page and health indicators for a Eureka instance default to"/info" and "/health" respectively, which are the default locations ofuseful endpoints in a Spring Boot Actuator application. You need tochange these, even for an Actuator application if you use anon-default context path or servlet path(e.g. server.servletPath=/foo) or management endpoint path(e.g. management.contextPath=/admin). Example:
If your app wants to be contacted over HTTPS you can set two flags inthe EurekaInstanceConfig, vizeureka.instance.[nonSecurePortEnabled,securePortEnabled]=[false,true]respectively. This will make Eureka publish instance informationshowing an explicit preference for secure communication. The SpringCloud DiscoveryClient will always return a URI starting with https for aservice configured this way, and the Eureka (native) instanceinformation will have a secure health check URL.
Because of the wayEureka works internally, it will still publish a non-secure URL forstatus and home page unless you also override those explicitly.You can use placeholders to configure the eureka instance urls,e.g.
If your app is running behind a proxy, and the SSL terminationis in the proxy (e.g. if you run in Cloud Foundry or other platformsas a service) then you will need to ensure that the proxy "forwarded"headers are intercepted and handled by the application. An embeddedTomcat container in a Spring Boot app does this automatically if ithas explicit configuration for the 'X-Forwarded-\*` headers. A signthat you got this wrong will be that the links rendered by your app toitself will be wrong (the wrong host, port or protocol).
Depending on the way the security rules are set up in your Cloudfoundry instance, you might be able to register and use the IP address of the host VM for direct service-to-service calls. This feature is not (yet) available on Pivotal Web Services (PWS).
If the application is planned to be deployed to an AWS cloud, then the Eureka instance will have to be configured to be AWS aware and this can be done by customizing the EurekaInstanceConfigBean the following way:
With this metadata, and multiple service instances deployed onlocalhost, the random value will kick in there to make the instanceunique. In Cloudfoundry the vcap.application.instance_id will bepopulated automatically in a Spring Boot application, so therandom value will not be needed.
Once you have an app that is a discovery client you can use it todiscover service instances from the Eureka Server. One way to do that is to use the nativecom.netflix.discovery.EurekaClient (as opposed to the SpringCloud DiscoveryClient), e.g.
By default, EurekaClient uses Jersey for HTTP communication. If you wishto avoid dependencies from Jersey, you can exclude it from your dependencies.Spring Cloud will auto configure a transport client based on SpringRestTemplate.
If you have deployed Eureka clients to multiple zones than you may prefer thatthose clients leverage services within the same zone before trying servicesin another zone. To do this you need to configure your Eureka clients correctly.
Next you need to tell Eureka which zone your service is in. You can do this usingthe metadataMap property. For example if service 1 is deployed to both zone 1and zone 2 you would need to set the following Eureka properties in service 1
To include Eureka Server in your project use the starter with group org.springframework.cloudand artifact id spring-cloud-starter-netflix-eureka-server. See the Spring Cloud Project pagefor details on setting up your build system with the current Spring Cloud Release Train.
Eureka can be made even more resilient and available by runningmultiple instances and asking them to register with each other. Infact, this is the default behaviour, so all you need to do to make itwork is add a valid serviceUrl to a peer, e.g.
You can add multiple peers to a system, and as long as they are allconnected to each other by at least one edge, they will synchronizethe registrations amongst themselves. If the peers are physicallyseparated (inside a data centre or between multiple data centres) thenthe system can in principle survive split-brain type failures.
In some cases, it is preferable for Eureka to advertise the IP Adressesof services rather than the hostname. Set eureka.instance.preferIpAddressto true and when the application registers with eureka, it will use itsIP Address rather than its hostname.
A service failure in the lower level of services can cause cascading failure all the way up to the user. When calls to a particular service is greater than circuitBreaker.requestVolumeThreshold (default: 20 requests) and failue percentage is greater than circuitBreaker.errorThresholdPercentage (default: >50%) in a rolling window defined by metrics.rollingStats.timeInMilliseconds (default: 10 seconds), the circuit opens and the call is not made. In cases of error and an open circuit a fallback can be provided by the developer.
Having an open circuit stops cascading failures and allows overwhelmed or failing services time to heal. The fallback can be another Hystrix protected call, static data or a sane empty value. Fallbacks may be chained so the first fallback makes some other business call which in turn falls back to static data.
To include Hystrix in your project use the starter with group org.springframework.cloudand artifact id spring-cloud-starter-netflix-hystrix. See the Spring Cloud Project pagefor details on setting up your build system with the current Spring Cloud Release Train.
The @HystrixCommand is provided by a Netflix contrib library called"javanica".Spring Cloud automatically wraps Spring beans with thatannotation in a proxy that is connected to the Hystrix circuitbreaker. The circuit breaker calculates when to open and close thecircuit, and what to do in case of a failure.
To configure the @HystrixCommand you can use the commandPropertiesattribute with a list of @HystrixProperty annotations. Seeherefor more details. See the Hystrix wikifor details on the properties available.
If you want some thread local context to propagate into a @HystrixCommand the default declaration will not work because it executes the command in a thread pool (in case of timeouts). You can switch Hystrix to use the same thread as the caller using some configuration, or directly in the annotation, by asking it to use a different "Isolation Strategy". For example:
You also have the option to set the hystrix.shareSecurityContext property to true. Doing so will auto configure an Hystrix concurrency strategy plugin hook who will transfer the SecurityContext from your main thread to the one used by the Hystrix command. Hystrix does not allow multiple hystrix concurrency strategy to be registered so an extension mechanism is available by declaring your own HystrixConcurrencyStrategy as a Spring bean. Spring Cloud will lookup for your implementation within the Spring context and wrap it inside its own plugin.
When using Hystrix commands that wrap Ribbon clients you want to make sure your Hystrix timeoutis configured to be longer than the configured Ribbon timeout, including any potentialretries that might be made. For example, if your Ribbon connection timeout is one second andthe Ribbon client might retry the request three times, than your Hystrix timeout shouldbe slightly more than three seconds.
To include the Hystrix Dashboard in your project use the starter with group org.springframework.cloudand artifact id spring-cloud-starter-hystrix-netflix-dashboard. See the Spring Cloud Project pagefor details on setting up your build system with the current Spring Cloud Release Train.
90f70e40cf