1. Eureka
2. Hystrix
3. Ribbon
4. Zuul
5. Config Server
6. CloudSleuth
- Can be standalone or cluster
- Netflix recommends a cluster per zone
- Create Eureka server
Steps:- Add spring-cloud-starter-eureka-server dependency in pom.xml
- Add @EnableEurekaServer annotation in primary class
- Entries in application.properties
eureka.client.register-with-eureka=false [for standalone setup] eureka.client.fetch-registry=false [for standalone setup] eureka.datacenter=[DC name] eureka.environment=[prod/dev/qa]
- Register a service with Eureka server
- Eureka in classpath leads to registration
- Service name, host info sent during bootstrap
- Sends heartbeat to the server at regular interval (30 sec by default); after 3 missed heartbeat the server is removed from the registry
Steps: - Add spring-cloud-starter-eureka-client dependency in pom.xml
- Add @EnableEurekaClient annotation in primary class; this registers the client and caches the registry
- Entries in bootstrap.properties
- spring.application.name=[name]
- Entries in application.properties
eureka.client.register-with-eureka=true eureka.client.fetch-registry=true
- Discover a service with Eureka server
- Client always works with local registry cache
- Client regular checks for changes in registry, downloads changes and updates cache
- Client can manually loadbalance or use Ribbon
- Client talks to the registry in closest Zone (AWS AZ)
- Evantually Consistent; when a service is registered with the server, it take some time before clients knows about the service. Takes few heartbeats before service metadata is available in client cache.
Steps: - Use steps to register the client with Eureka server
- Add following while calling another service
@LoadBalanced @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); }
- Use Service ID instead of hardcoded URL
- Custom health check
- Add a custom class
- implement HealthIndicator interface and override health()
- Add following in application.properties
- eureka.client.healthcheck.enabled=true
- Enables resilience in microservices
- Bulkhead pattern
- Once a failure is detected, Hystrix open the circuit. Then it sends request occasionally to check if service is up, if so it closes the circuit.
- Creating a hystrix protected service
- Add spring-cloud-starter-hystrix in pom.xml of calling service
- Annotate primary class of calling service with @EnableCircuitBreaker
- Annotate the method calling other service with @HystrixCommand(fallbackMetho="myFallbackMethodName") and define fallback method
- myFallbackMethodName should have the same signature as the method annotated with @HystrixCommand
- Hystrix heartbeat: http://host:port/hystrix.stream
- Client-side software load balancer
- Netflix came up with this as AWS ELBs are mostly public device facing load balancers, they needed something for mid-tier requests.
- Offers
- storage of server addresses ("server list")
- server freshness check ("ping")
- server selection criteria ("rules")
- Also has basic circuit-breaker logic, if rest client fails to make a call for a number of times, new requests are not sent to it.
- @LoadBalanced or @RibbonClient annotation
- Configuring Ribbon
- Add spring-cloud-starter-ribbon (listed under "cloud routing" on start.spring.io)
- List of servers can be provided in code, configuration or Eureka
- Use @LoadBalanced RestTemplate
- How Ribbon and Eureka work together
- Server list comes from Eureka server
- Ribbon delegates "ping" to Eureka
- Ribbon cache comes from Eureka client
- When Ribbon is used without Eureka, we need to provide listOfServers in application.properties
- Is a microproxy, helps in routing traffic in microservices architecture
- Can be used to handle cross-cutting concerns like authentication, monitoring, logging, throttling etc.
- Integrates with Eureka, Ribbon, Hystrix
- Uses semaphore model of Hystrix instead of thread
- @ZuulProxy vs @EnableZuulProxy
- @ZuulProxy has default intergration with Eureka, Ribbon
- @ZuulProxy has additional routes & filter
- @EnableZuulProxy is "Blank" Zuul server, others have to be added separately
- Creating Zuul proxy
- Add spring-cloud-starter-zuul and actuator dependencies in pom.xml
- Add spring-cloud-starter-eureka (optional) for service discovery
- Backend location can be URL or service ID. URL doesn't get load balanced using Ribbon. Preferrably use Service ID.
- Control over path of route: ignore services discovered by Eureka, fine-grained control on route
- Regex to define some route patterns
zuul.ignoredServices=* zuul.routes.employees.path=/emps/** zuul.routes.employees.serviceId=employee_service [Eureka registered service name]
- Adding filters
- Create a new class, extend ZuulFilter
- Override methods: run, shouldFilter, filterOrder, filterType
- Eg shouldFilter()
public boolen shouldFilter() { boolean isMobile=false; RequestContext ctx = getCurrentContext(); String param = ctx.getRequest().getParameter("source") if(param !=null && param.equals("mobile") isMobile=true; return isMobile; }
- store and serve distributed configuration across multiple application and environments
- Setting up config server
- Add spring-cloud-config-server in pom.xml
- Add @EnableConfigServer in primary class
- Create git repository
- create a folder config-server-repo
- add 3 files; format: [spring.application.name mentioned in client bootstrap.properties]-[active profile]
- config-server-client.properties, config-server-client-dev.properties, config-server-client-prod.properties
- commit the files in git
- add following application.properties
server.port=8888 spring.cloud.config.server.git.uri=${USERPROFILE}\\Desktop\\config-server-repo #Git repo location.
- Now client configurations can be queried
- /[spring.application.name]-[active profile]
- Eg:
http://localhost:8888/config-server-client.properties
http://localhost:8888/config-server-client-dev.properties
http://localhost:8888/config-server-client-prod.properties
- Setting up config client
- Add spring-cloud-starter-config in pom.xml
- Add bootstrap.properties
spring.application.name=config-client spring.profiles.active=development spring.cloud.config.uri=http://localhost:8888
- Access properties keys in code
@Value("${msg}") # msg is the key included in .properties file for this client private String msg;
- Introduces unique IDs to logging which makes it possible to find how a single request travels from one microservice to the next.
- adds two types of IDs
- Trace ID: Remains same as one microservice call the next
- Span ID: Changes between microservice calls
- Steps
- Add spring-cloud-starter-slueth in pom.xml
- Add this in application code private static final Logger LOG = Logger.getLogger(SleuthSampleApplication.class.getName());
- Log will look like
2016-06-15 16:55:56.334 INFO [UserService,8067a0f0cbac73e9,d2f8d1e3a97c65f9,false,false]
where
UserService: service name
8067a0f0cbac73e9: Trace ID
d2f8d1e3a97c65f9: Span ID