Skip to content

Instantly share code, notes, and snippets.

@brijesh-deb
Last active May 19, 2018 11:58
Show Gist options
  • Save brijesh-deb/3e305ef224329c9d313c99c42d5319b5 to your computer and use it in GitHub Desktop.
Save brijesh-deb/3e305ef224329c9d313c99c42d5319b5 to your computer and use it in GitHub Desktop.
#SpringCloud #Microservice #NetflixOSS #Netflix

1. Eureka
2. Hystrix
3. Ribbon
4. Zuul
5. Config Server
6. CloudSleuth

Eureka

Eureka Server

  • 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

Hystrix

  • 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

Ribbon

  • 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

Zuul

  • 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;
      }
    

Spring Config Server

  • 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.
    
  • 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; 
    

Spring Cloud Sleuth

  • 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment