This playground is for learning Spring Cloud and Kotlin via examples.
Read this in other languages:
💚 Start here.
Cloud-native is an approach to building and running applications that exploits the advantages of the cloud computing model.
Microservices is an architectural approach to developing an application as a collection of small services; each service implements business capabilities, runs in its own process and communicates via an HTTP API. Each microservice can be deployed, upgraded, scaled, and restarted independent of other services in the application, typically as part of an automated system.
We're breaking large applications into smaller pieces called 'services'. And each of these services can be deployed and scaled on their own. How does one service locate another?
Module | URL |
---|---|
discovery-server | http://host:8761/eureka |
There're multiple ways you can discover services in Spring Cloud:
This project specifically focuses on the last one, the Spring Cloud Netflix project. The US-based giant of cloud-based streaming media services, namely Netflix, has open-sourced its framework of microservice tools.
For the sake of simplicity, there's a single instance of Eureka server. Therefore Eureka server is configured not to trying register itself with its peers. You may want to have multiple discovery servers for high availability in production, so change the following properties:
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
Eureka is constantly ensuring that application services that it's returning or handing back to clients are healthy and available. And it's also ensuring that in case if Discovery Server goes down all clients still continue to operate.
Eureka was built with high availability in mind:
- The registry is distributed (cached locally on every client).
- Clients can operate without discovery server (if this server goes down).
- Clients fetch deltas to update registry.
A web based Eureka dashboard is enabled by default. It shows useful information such as services metadata.
In local environment it's available at http://localhost:8761
Module | URL |
---|---|
weather-service | http://host:port/weather |
The @EnableDiscoveryClient
annotation is used to turn WeatherServiceApplication
into a client of the Discovery Server and it causes it to register with the Discovery Server when it starts up.
Module | URL |
---|---|
weather-app | http://host:port/current/weather |
Module | URL |
---|---|
datetime-service | http://host:port/datetime |
The @EnableDiscoveryClient
annotation is used to turn DatetimeServiceApplication
into a client of the Discovery Server and it causes it to register with the Discovery Server when it starts up.
Module | URL |
---|---|
datetime-app | http://host:port/current/datetime |
Module | URL |
---|---|
client | http://host:port |
The @EnableDiscoveryClient
annotation is used to turn ClientApplication
into a client of the Discovery Server.
The Client does not need to register with Eureka because it does not want anybody to discover it so the following property is set to false:
eureka.client.register-with-eureka=false
In a Distributed System one thing is absolutely certain... FAILURE IS INEVITABLE.
A particularly bad effect of failures in a distributed system is a cascading failure. From Wikipedia:
It is a process in a system of interconnected parts in which the failure of one or few parts can trigger the failure of other parts and so on.
How to embrace failure?
- Fault tolerance
- Graceful degradation
- Constrain resources
Circuit breaker design pattern is a design pattern used in modern software development. It is used to detect failures and encapsulates the logic of preventing a failure from constantly recurring
(From Wikipedia)
Netflix Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
See How it works.
Module | URL |
---|---|
hystrix-dashboard | http://host:port/hystrix |
Documentation: Circuit Breaker: Hystrix Dashboard
Module | URL |
---|---|
turbine | http://host:3000/turbine.stream |
Hystrix dashboard can only monitor one microservice at a time. If there are many microservices, then the Hystrix dashboard pointing to the service has to be changed every time when switching the microservices to the monitor. It is tedious.
Turbine (provided by the Spring Cloud Netflix project), aggregates multiple instances Hystrix metrics streams, so the dashboard can display an aggregate view.
Config example:
turbine.app-config=weather-app,datetime-app
turbine.cluster-name-expression='default'
Before the first build you need to take additional steps.
- Clone the repository.
- Define some environment variables.
- 📗 TODO
You have a freedom of choosing build tools for this project: Gradle or your favourite IDE. IntelliJ IDEA, STS / Eclipse, or NetBeans should handle this task smoothly.
./gradlew :discovery-server:bootRun
./gradlew :weather-service:bootRun
./gradlew :weather-app:bootRun
./gradlew :client:bootRun
./gradlew :datetime-service:bootRun
./gradlew :datetime-app:bootRun
./gradlew :turbine:bootRun
./gradlew :hystrix-dashboard:bootRun
- Import root project in IntelliJ IDEA
- Sync project files with Gradle (initial sync may happen automatically)
- Now you should have multiple run configurations for every module. Run them one-by-one:
- DiscoveryServerApplication
- WeatherServiceApplication
- WeatherAppApplication
- ClientApplication
- DatetimeServiceApplication
- DatetimeAppApplication
- TurbineApplication
- HystrixDashboardApplication
Tip: make sure that you run them on different ports and these ports are free, otherwise you'll get an error.
📗 TODO
Travis CI |
---|
This project is licensed under the terms of the GNU GPL v3 license.