- Learning : https://www.udemy.com/course/microservices-with-spring-boot-and-spring-cloud/learn/lecture/8005704#overview
- Resources : GitHub and FAQ
- Instructor: Ranga Rao Karanam
https://www.udemy.com/certificate/UC-ed0e4498-34b0-485f-bce4-54782fc08206/
- 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
- Install Docker
- Create a Config repo
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
- Once the server is running, you can view traces with the Zipkin UI at http://localhost:9411/zipkin
- Install RabbitMQ
- Install Zipkin
- Once the server is running, you can view traces with the Zipkin UI at http://localhost:9411/zipkin
- 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://guest@127.0.0.1:5672/, localPort= 49282]
- Run the Eureka Naming Server
cd netflix-eureka-naming-server
./mvnw spring-boot:run
- 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"
- Run one instance of the Conversion service
cd currency-conversion-service
./mvnw spring-boot:run
- Run the Zuul Api Gateway server
cd netflix-zuul-api-gateway-server
./mvnw spring-boot:run
Look at the Eureka UI, all your 4 instances should be UP :
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 :
- 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
andspring.cloud.config.uri
in configuration file renamed as bootstrap.properties. seehttp://{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.
- 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
- 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
- Server :
- 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...
- Create a component for the Zuul API Gateway server.
spring-cloud-starter-netflix-zuul
,@EnableZuulProxy
- Decide/implement what should it do when it intercepts a request.
ZuulFilter
- Make sure all important requests are configured to pass through the Zuul API Gateway.
@FeignClient(name = {api-gateway-app-name})
,http://{zullGatewayLocation}/{serviceName}/{uri}
example http://localhost:8765/currency-conversion-service/currency-converter-feign/from/EUR/to/INR/quantity/80 or http://localhost:8765/currency-exchange-service/currency-exchange/from/EUR/to/INR
- Create a component for the Zuul API Gateway server.
- 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)
- Start Zipkin server with 2 commands and see Zipkin UI: 1)
- 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 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 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")
For further reference, please consider the following sections:
- Spring Cloud Config
- Bootstrap Application Context
- Spring Cloud OpenFeign : Declarative REST Client
- Spring Cloud Ribbon : Client-side load-balancing
- Spring Cloud Eureka : Service Registration and Discovery
- Spring Cloud Zuul API Gateway : Intelligent Routing and Filtering
- Spring Cloud Sleuth : Distributed Tracing
- Rabbit MQ : Message Broker
- Zipkin : Distributed Tracing System
- Spring Cloud Bus : Distributed Actuator/Communication channel
- Hystrix : Circuit Breaker pattern
The following guides illustrate how to use some features concretely:
- Centralized Configuration
- Spring Cloud OpenFeign : Declarative REST Client
- Spring Cloud Ribbon : Client-side load-balancing
- Spring Cloud Eureka : Service Registration and Discovery
- Spring Cloud Zuul API Gateway : Intelligent Routing and Filtering
- Spring Cloud Sleuth : Distributed Tracing
- Rabbit MQ : Tutorials
- Zipkin : Distributed Tracing System.
- Spring Cloud Bus : Distributed Actuator/Communication channel
- Hystrix : Circuit Breaker pattern]
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.