Skip to content

kendyjm/microservices-spring-cloud

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Master Microservices with Spring Boot and Spring Cloud : PART 2 - Microservices with Spring Cloud

Context

Udemy Certificate of completion (May 2020)

https://www.udemy.com/certificate/UC-ed0e4498-34b0-485f-bce4-54782fc08206/

Content

  • Establishing Communication between Microservices
  • Centralized Microservice Configuration with Spring Cloud Config Server
  • Using Spring Cloud Bus to exchange messages about Configuration updates
  • Simplify communication with other Microservices using Feign REST Client
  • Implement client side load balancing with Ribbon
  • Implement dynamic scaling using Eureka Naming Server and Ribbon
  • Implement API Gateway with Zuul
  • Implement Distributed tracing with Spring Cloud Sleuth and Zipkin
  • Implement Fault Tolerance with Hystrix

diagram-microservices

Getting Started

Overview of the services

Prerequistes

Quick startup with Docker (recommended)

Just run the docker images of RabbitMq and Zipkin:

  • RabbitMQ : docker run -d --rm --name rabbitmq -p 5672:5672 rabbitmq:latest
  • Zipkin : docker run -d --name zipkin-tracing -e RABBIT_URI='amqp://{your_local_ip_ex:192.168.1.38}' -p 9411:9411 openzipkin/zipkin:latest

Manual installation and running (alternative)

Run the services

  1. Firstly, run the Config Server and check its logs to see a valid connection to RabbitMq:
cd spring-cloud-config-server
./mvnw spring-boot:run

INFO o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#5bd6c5aa:133/SimpleConnection@3eb183a [delegate=amqp://[email protected]:5672/, localPort= 49282]
  1. Run the Eureka Naming Server
cd netflix-eureka-naming-server
./mvnw spring-boot:run
  1. Run some instances of the Exchange service by specifying the server port
cd currency-exchange-service
./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8000"
./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8001"
  1. Run one instance of the Conversion service
cd currency-conversion-service
./mvnw spring-boot:run
  1. Run the Zuul Api Gateway server
cd netflix-zuul-api-gateway-server
./mvnw spring-boot:run

Checks the state of the services

Look at the Eureka UI, all your 4 instances should be UP :

eureka-naming-server

Request the application

Convert 80EUR in INR by calling the conversion service through the Api Gateway :

curl http://localhost:8765/currency-conversion-service/currency-converter-feign/from/EUR/to/INR/quantity/80

{
  "id": 1002,
  "from": "EUR",
  "to": "INR",
  "conversionMultiple": 75.00,
  "quantity": 80,
  "totalCalculatedAmount": 6000.00,
  "port": 8000
}

Send a 2nd call, check the port value, the request reached the 2nd instance of the Exchange service.

curl http://localhost:8765/currency-conversion-service/currency-converter-feign/from/EUR/to/INR/quantity/80

{
  "id": 1002,
  "from": "EUR",
  "to": "INR",
  "conversionMultiple": 75.00,
  "quantity": 80,
  "totalCalculatedAmount": 6000.00,
  "port": 8001
}

Check Zipkin UI to see the path followed by these 2 requests :

zipkin-ui-requests zipkin-ui-request-001 zipkin-ui-request-002

Implementation

  • Spring Cloud Config Server : spring-cloud-config-server (config-server) as a dependency, annotation @EnableConfigServer in main class, spring.cloud.config.server.git.uri in configuration file application.properties
  • Any service : spring-cloud-starter-config (config-client) as a dependency, spring.application.name and spring.cloud.config.uri in configuration file renamed as bootstrap.properties. see http://{configServerLocation}/{serviceName}/{default|dev|qa...} to display the retrieved/current configuration of a service.
    • A service requests, at startup, its config to the server. to reflect a config change, restart the service or call actuator endpoint http://{appHost}:{appPort}/application/refresh
      • In a cloud/microservices environment, go to every single client and reload configuration by accessing actuator endpoint is a pain...see below how Spring Cloud Bus solve this problem.
  • Git Repository : contains configuration files for each service/env : {spring.application.name}[dev|qa|blabla].properties
  • Spring Cloud OpenFeign : Is a declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations (see @FeignClient)
  • Spring Cloud Ribbon : allows client-side loadbalancing (see spring-cloud-starter-netflix-ribbon, @RibbonClient and {serviceName}.ribbon.listOfServers). Somes details about rules available.
  • Spring Cloud Eureka : service registry, useful because it makes client-side load-balancing easier and decouples service providers from consumers without the need for DNS.
    • Server : spring-cloud-starter-netflix-eureka-server, @EnableEurekaServer, eureka.client.register-with-eureka, eureka.client.fetch-registry, Eureka UI
    • Client : spring-cloud-starter-netflix-eureka-client, @EnableDiscoveryClient, eureka.client.service-url.default-zone
  • Spring Cloud Zuul : Api Gateway, all calls get routed through the API gateway, with common features like authentication, authorization and security, rate limits, fault tolerance, service aggregation; it's a great place for debugging, analytics...
  • Spring Cloud Sleuth : Distributed tracing, look for the trace ID in log message. Spring Cloud Sleuth is a layer over a Tracer library named Brave. spring-cloud-starter-sleuth, brave.sampler.Sampler
  • Message Broker : Use of message broker to let the distributed tracing server consumes the messages/logs produced by the apps/services.
    • Here we used Rabbit MQ
    • Kafka is another well-known message broker
  • Zipkin : Distributed Tracing System. Zipkin in listening to our Rabbit MQ server. trace data consumed by Zipkin are validated, stored, indexed for lookups. Zipkin provides API and UI for retrieving&viewing traces. Latest release
    • Start Zipkin server with 2 commands and see Zipkin UI: 1) set RABBIT_URI=amqp://localhost 2) java -jar zipkin-server-2.7.0-exec.jar
    • Dependencies to add to our services : spring-cloud-starter-zipkin (to trace message in a correct ziplin format), org.springframework.amqp.spring-rabbit (to put a trace message into Rabbit MQ)
  • Spring Cloud Bus : uses lightweight message broker to link distributed system nodes. The primary usage is to broadcast configuration changes or other management information. We can think about it as a distributed Actuator.
    • Spring Cloud Bus uses Spring Cloud Stream to broadcast the messages. So, to get messages to flow, you need only include the binder implementation of your choice in the classpath. There are convenient starters for the bus with AMQP (RabbitMQ) and Kafka (spring-cloud-starter-bus-[amqp|kafka]) add it to your config-server and services.
    • Call http://{appHost}:{appPort}/application/bus-refresh actuator endpoint to refresh every instance of a service
      • With multi instances for multi services you can create a REST service which hits one instance of each service.
      • Use of auto-refresh could be a good option, see spring-cloud-config-monitor
  • Spring Cloud Hystrix : enable Fault Tolerance by implementing the circuit breaker pattern. Having an open circuit stops cascading failures and allows overwhelmed or failing services time to recover. The fallback can be another Hystrix protected call, static data, or a sensible empty value. Fallbacks may be chained so that the first fallback makes some other business call, which in turn falls back to static data.
    • spring-cloud-starter-netflix-hystrix, @EnableHystrix, @HystrixCommand(fallbackMethod = "myfallbackMethod")

Reference Documentation

For further reference, please consider the following sections:

Guides

The following guides illustrate how to use some features concretely:

Spring Cloud Netflix Maintenance Mode

Some dependencies used in this project are in maintenance mode:

  • Ribbon
  • Zuul
  • Hystrix

The decision to move most of the Spring Cloud Netflix projects to maintenance mode was a response to Netflix not continuing maintenance of many of the libraries that Spring provided support for. See this blog entry for more information on maintenance mode and a list of suggested replacements for those libraries.

Debugging Problems

More Reading about Microservices

Design and Governance of Microservices

12 Factor App