:github-tag: master
:github-repo: spring-cloud/spring-cloud-netflix
:github-raw: http://raw.github.com/{github-repo}/{github-tag}
:github-code: http://github.com/{github-repo}/tree/{github-tag}
= Spring Cloud Netflix

include::intro.adoc[]

== Service Discovery: Eureka Clients

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.

When clients register with Eureka, they provide eureka with meta-data about themselves such as host and port, health indicator URL, home page etc.  Eureka receives heartbeat messages from each instance belonging to a service.  If the heartbeat fails over a configurable timetable, the instance is normally removed from Eureka.

Example eureka client:

[source,java,indent=0]
----
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello world";
    }
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}
----

(i.e. utterly normal Spring Boot app). Configuration is required to locate the Eureka server. Example:


.application.yml
----
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
----

where "defaultZone" is a magic string fallback value that provides the
service URL for any client that doesn't express a preference
(i.e. it's a useful default).

The default application name (service ID), virtual host and non-secure
port, taken from the `Environment`, are `${spring.application.name}`,
`${spring.application.name}` and `${server.port}` respectively.

`@EnableEurekaClient` makes the app into both a Eureka "instance"
(i.e. it registers itself) and a "client" (i.e. it can query the
registry to locate other services). The instance behaviour is driven
by `eureka.instance.*` configuration keys, but the defaults will be
fine if you ensure that your application has a
`spring.application.name` (this is the default for the Eureka service
ID, or VIP).

See {github-code}/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java[EurekaInstanceConfigBean] and {github-code}/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java[EurekaClientConfigBean] for more details of the configurable options.

=== Using the DiscoveryClient

Once you have an app that is `@EnableEurekaClient` you can use it to
discover service instances from the <<spring-cloud-eureka-server,
Eureka Server>>. One way to do that is to use the native `DiscoveryClient`, e.g.

----
@Autowired
private DiscoveryClient discoveryClient;

public String serviceUrl() {
    InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
    return instance.getHomePageUrl();
}
----

[TIP]
====
Don't use the `DiscoveryClient` in `@PostConstruct` method (or
anywhere where the `ApplicationContext` might not be started yet). It
is initialized in a `SmartLifecycle` (with `phase=0`) so the earliest
you can rely on it being available is in another `SmartLifecycle` with
higher phase.
====

=== Alternatives to the DiscoveryClient

You don't have to use the raw Netflix `DiscoveryClient` and usually it
is more convenient to use it behind a wrapper of some sort. Spring
Cloud has support for <<spring-cloud-feign, Feign>> (a REST client
builder) and also <<spring-cloud-ribbon, Spring `RestTemplate`>> using
the logical Eureka service identifiers (VIPs) instead of physical
URLs.

=== Why is it so Slow to Register a Service?

Being an instance also involves a periodic heartbeat to the registry
(via the client's `serviceUrl`) with default duration 30 seconds. A
service is not available for discovery by clients until the instance,
the server and the client all have the same metadata in their local
cache (so it could take 3 hearbeats). You can change the period using
`eureka.instance.leaseRenewalIntervalInSeconds` and this will speed up
the process of getting clients connected to other services. In
production it's probably better to stick with the default because
there are some computations internally in the server that make
assumptions about the lease renewal period.

[[spring-cloud-eureka-server]]
== Service Discovery: Eureka Server

Example eureka server:

[source,java,indent=0]
----
@Configuration
@EnableAutoConfiguration
@EnableEurekaServer
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}
----

The server has a home page with a UI, and HTTP API endpoints per the
normal Eureka functionality under `/eureka/*`.

Eureka background reading: see https://github.com/cfregly/fluxcapacitor/wiki/NetflixOSS-FAQ#eureka-service-discovery-load-balancer[flux capacitor] and https://groups.google.com/forum/?fromgroups#!topic/eureka_netflix/g3p2r7gHnN0[google group discussion].

[TIP]
====
You can run the Eureka server as an executable JAR (or WAR) using the
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins[Spring
Boot build tools], but to avoid problems with classpath scanning in
Jersey 1.x you have to tell the build plugins to unpack the jars that
contain JAX-RS resources, e.g. (for Maven)

.pom.xml
[source,xml,indent=0]
----
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <requiresUnpack>
                        <dependency>
                            <groupId>com.netflix.eureka</groupId>
                            <artifactId>eureka-core</artifactId>
                        </dependency>
                        <dependency>
                            <groupId>com.netflix.eureka</groupId>
                            <artifactId>eureka-client</artifactId>
                        </dependency>
                    </requiresUnpack>
                </configuration>
            </plugin>
----

or with Gradle

.build.gradle
[source,java,indent=0]
----
apply plugin: 'spring-boot'
springBoot {
    requiresUnpack = ['com.netflix.eureka:eureka-core','com.netflix.eureka:eureka-client']
}
----
====

[NOTE]
====
The Eureka server is tied to log4j and doesn't work with logback, 
so the dependency configuration
has to be tweaked compared to a normal Spring Boot app. The 
`spring-cloud-starter-eureka-server` does this for you, but if you
add logback transitively through another dependency you will need to
exclude it manually, e.g. in Maven

.pom.xml
[source,xml,indent=0]
----
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<exclusions>
				<exclusion>
					<artifactId>spring-boot-starter-logging</artifactId>
					<groupId>org.springframework.boot</groupId>
				</exclusion>
			</exclusions>
		</dependency>
----
====

=== High Availability, Zones and Regions

The Eureka server does not have a backend store, but the service
instances in the registry all have to send heartbeats to keep their
resistrations up to date (so this can be done in memory). Clients also
have an in-memory cache of eureka registrations (so they don't have to
go to the registry for every single request to a service).

By default every Eureka server is also a Eureka client and requires
(at least one) service URL to locate a peer. If you don't provide it
the service will run and work, but it will shower your logs with a lot
of noise about not being able to register with the peer.

=== Standalone Mode

The combination of the two caches (client and server) and the
heartbeats make a standalone Eureka server fairly resilient to
failure, as long as there is some sort of monitor or elastic runtime
keeping it alive (e.g. Cloud Foundry). In standalone mode, you might
prefer to switch off the client side behaviour, so it doesn't keep
trying and failing to reach its peers. Example:

.application.yml (Standalone Eureka Server)
----
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client: 
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
----

Notice that the `serviceUrl` is pointing to the same host as the local
instance.

=== Peer Awareness

Eureka can be made even more resilient and available by running
multiple instances and asking them to register with each other. In
fact, this is the default behaviour, so all you need to do to make it
work is add a valid `serviceUrl` to a peer, e.g.

.application.yml (Two Peer Aware Eureka Servers)
----

---
spring:
  profiles: peer1
eureka:
  instance:
    hostname: peer1
  client: 
    serviceUrl:
      defaultZone: http://peer2/eureka/

---
spring:
  profiles: peer2
eureka:
  instance:
    hostname: peer2
  client: 
    serviceUrl:
      defaultZone: http://peer1/eureka/
----

In this example we have a YAML file that can be used to run the same
server on 2 hosts (peer1 and peer2), by running it in different
Spring profiles. You could use this configuration to test the peer
awareness on a single host (there's not much value in doing that in
production) by manipulating `/etc/hosts` to resolve the host names. In
fact, the `eureka.instance.hostname` is not needed if you are running
on a machine that knows its own hostname (it is looked up using
`java.net.InetAddress` by default).

You can add multiple peers to a system, and as long as they are all
connected to each other by at least one edge, they will synchronize
the registrations amongst themselves. If the peers are physically
separated (inside a data centre or between multiple data centres) then
the system can in principle survive split-brain type failures.

== Circuit Breaker: Hystrix Clients

Netflix has created a library called https://github.com/Netflix/Hystrix[Hystrix] that implements the http://martinfowler.com/bliki/CircuitBreaker.html[circuit breaker pattern].  In a microservice architecture it is common to have multiple layers of service calls.

.Microservice Graph
image::HystrixGraph.png[]

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 reach a certain threshold (20 failures in 5 seconds is the default in Hystrix), 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.

.Hystrix fallback prevents cascading failures
image::HystrixFallback.png[]

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.

Example boot app:

----
@Configuration
@EnableAutoConfiguration
@EnableHystrix
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}

@Component
public class StoreIntegration {

    @HystrixCommand(fallbackMethod = "defaultStores")
    public Object getStores(Map<String, Object> parameters) {
        //do stuff that might fail
    }

    public Object defaultStores(Map<String, Object> parameters) {
        return /* something useful */;
    }
}

----

The `@HystrixCommand` is provided by a Netflix contrib library called
https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica["javanica"].
Spring Cloud automatically wraps Spring beans with that
annotation in a proxy that is connected to the Hystrix circuit
breaker. The circuit breaker calculates when to open and close the
circuit, and what to do in case of a failure.

To configure the `@HystrixCommand` you can use the `commandProperties`
attribute with a list of `@HystrixProperty` annotations.  See
https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration[here]
for more details.  See the https://github.com/Netflix/Hystrix/wiki/Configuration[Hystrix wiki]
for details on the properties available.

The state of the connected circuit breakers are also exposed in the
`/health` endpoint of the calling application. 

[source,json,indent=0]
----
{
    "hystrix": {
        "openCircuitBreakers": [
            "StoreIntegration::getStoresByLocationLink"
        ],
        "status": "CIRCUIT_OPEN"
    },
    "status": "UP"
}
----

== Circuit Breaker: Hystrix Dashboard

One of the main benefits of Hystrix is the set of metrics it gathers about each HystrixCommand.  The Hystrix Dashboard displays the health of each circuit breaker in an efficient manner.

.Hystrix Dashboard
image::Hystrix.png[]

To run the Hystrix Dashboard annotate your Spring Boot main class with `@EnableHystrixDashboard`.  You then visit `/hystrix/index.html` and point the dashboard to an individual instances `/hystrix.stream` endpoint in a Hystrix client application.

=== Turbine

Looking at an individual instances Hystrix data is not very useful in terms of the overall health of the system.  https://github.com/Netflix/Turbine[Turbine] is an application that aggregates all of the relevant `/hystrix.stream` endpoints into a combined `/turbine.stream` for use in the Hystrix Dashboard.  Individual instances are located via Eureka.  Running Turbine is as simple as annotating your main class with the `@EnableTurbine` annotation.

`turbine.appConfig` is a list of eureka serviceId's that turbine will use to lookup instances.  `turbine.aggregator.clusterConfig` is used to group instances together.  This comes from the eureka `InstanceInfo`.  The clusterName is a SPEL expression evaluated against the InstanceInfo.  The default clusterNameExpression is `appName`.  The turbine stream is then used in the Hystrix dashboard using a url that looks like: http://my.turbine.sever:8080/turbine.stream?cluster=CUSTOMERS

The `cluster` parameter must match an entry in `turbine.aggregator.clusterConfig`.

----
turbine:
  aggregator:
    clusterConfig: CUSTOMERS
  appConfig: customers
----

The clusterName can be customized by a SPEL expression in `turbine.clusterNameExpression`.  For example, `turbine.clusterNameExpression=aSGName` would get the clustername from the AWS ASG name.

[[spring-cloud-feign]]
== Declarative REST Client: Feign

https://github.com/Netflix/feign[Feign] is a declarative web service client.  It makes writing web service clients easier.  To use Feign create an interface and annotate it.  It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders.  Spring Cloud adds support for Spring MVC annotations and for using the same `HttpMessageConverters` used by default in Spring Web.  Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign.

Example spring boot app

[source,java,indent=0]
----
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
public class Application extends FeignConfigurer {
    @Bean
    public StoreClient storeClient() {
        //loadBalance plugs Feign into ribbon.  feign() works without load balancing.
        return loadBalance(StoreClient.class, "http://stores");
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
----

.StoreClient.java
[source,java,indent=0]
----
public interface StoreClient {
    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    List<Store> getStores();

    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    Store update(@PathParameter("storeId") Long storeId, Store store);
}
----

[[spring-cloud-ribbon]]
== Client Side Load Balancer: Ribbon

Usage of `LoadBalancerClient` directly:

[source,java,indent=0]
----
public class MyClass {
    @Autowired
    private LoadBalancerClient loadBalancer;

    public void doStuff() {
        ServiceInstance instance = loadBalancer.choose("stores");
        URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
        // ... do something with the URI
    }
}
----

Indirect usage via `RestTemplate`.

[source,java,indent=0]
----
public class MyClass {
    @Autowired
    private RestTemplate restTemplate;

    public String doOtherStuff() {
        String results = restTemplate.getForObject("http://stores/stores", String.class);
        return results;
    }
}
----

== External Configuration: Archaius

https://github.com/Netflix/archaius[Archaius] is the Netflix client side configuration library.  It is the library used by all of the Netflix OSS components for configuration.  Archaius is an extension of the http://commons.apache.org/proper/commons-configuration[Apache Commons Configuration] project.  It allows updates to configuration by either polling a source for changes or for a source to push changes to the client.  Archaius uses Dynamic<Type>Property classes as handles to properties.

.Archaius Example
[source,java]
----
class ArchaiusTest {
    DynamicStringProperty myprop = DynamicPropertyFactory
            .getInstance()
            .getStringProperty("my.prop");

    void doSomething() {
        OtherClass.someMethod(myprop.get());
    }
}
----

Archaius has its own set of configuration files and loading priorities.  Spring applications should generally not use Archaius directly., but the need to configure the Netflix tools natively remains.  Spring Cloud has a Spring Environment Bridge so Archaius can read properties from the Spring Environment.  This allows Spring Boot projects to use the normal configuration toolchain, while allowing them to configure the Netflix tools, for the most part, as documented.

== Router and Filter: Zuul

Routing in an integral part of a microservice architecture.  For example, `/` may be mapped to your web application, `/api/users` is mapped to the user service and `/api/shop` is mapped to the shop service.  https://github.com/Netflix/zuul[Zuul] is a JVM based router and server side load balancer by Netflix.

http://www.slideshare.net/MikeyCohen1/edge-architecture-ieee-international-conference-on-cloud-engineering-32240146/27[Netflix uses Zuul] for the following:

* Authentication
* Insights
* Stress Testing
* Canary Testing
* Dynamic Routing
* Service Migration
* Load Shedding
* Security
* Static Response handling
* Active/Active traffic management

Zuul's rule engine allows rules and filters to be written in essentially any JVM language, with built in support for Java and Groovy.

[[netflix-zuul-reverse-proxy]]
=== Embedded Zuul Reverse Proxy

Spring Cloud has created an embedded Zuul proxy to ease the development of a very common use case where a UI application wants to proxy calls to one or more back end services.  To enable it, annotate a Spring Boot main class with `@EnableZuulProxy`, and this forwards local calls to the appropriate service.  By convention, a service with the Eureka ID "users", will receive requests from the proxy located at `/users`.  The proxy uses Ribbon to locate an instance to forward to via Eureka. To skip having a service automatically added from eureka, set `zuul.ignored-services = service1`. 

To augment or change the proxy routes, you can add external
configuration like the following:

.application.yml
[source,yaml]
----
 zuul:
  routes:
    users: /myusers/**
----

This means that http calls to "/myusers" get forwarded to the "users"
service. This configuration is useful for a user interface to proxy to
the backend services it requires (avoiding the need to manage CORS and
authentication concerns independently for all the backends).

To get more fine-grained control over a route you can specify the path
and the serviceId independently:

.application.yml
[source,yaml]
----
 zuul:
  routes:
    users:
      path: /myusers/**
      serviceId: users_service
----

This means that http calls to "/myusers" get forwarded to the
"users_service" service.  The route has to have a "path" which can be
specified as an ant-style pattern, so "/myusers/*" only matches one
level, but "/myusers/**" matches hierarchically. 

The location of the backend can be specified as either a "serviceId"
(for a Eureka service) or a "url" (for a physical location), e.g.

.application.yml
[source,yaml]
----
 zuul:
  routes:
    users:
      path: /myusers/**
      url: http://example.com/users_service
----

Forwarding to the service is protected by a Hystrix circuit breaker so if a service is down the client will see an error, but once the circuit is open the proxy will not try to contact the service.

To add a prefix to all mappings, set `zuul.prefix` to a value, such as `/api`.  To strip the proxy prefix from the request before the request is forwarded set `zuul.stripPrefix = true`. You can also strip the non-wildcard prefix from individual routes, e.g.

.application.yml
[source,yaml]
----
 zuul:
  routes:
    users:
      path: /myusers/**
      stripPrefix: true
----

In this example requests to "/myusers/101" will be forwarded to "/101" on the "users" service (the path is stripped up to the first wildcard character).

The `X-Forwarded-Host` header added to the forwarded requests by default.  To turn it off set `zuul.addProxyHeaders = false`.

An application with the `@EnableZuulProxy` could act as a standalone server if you set a default route ("/"), for example `zuul.route.home: /` would route all traffic (i.e. "/**") to the "home" service.

