Spring Cloud
Spring Cloud
Spring Cloud:
- To develop application using microservices architecture concept.
- Microservice is design or theory, for this coding is “Spring cloud”
Components:
1. Microservices (Spring ReST API)
2. Register and Discovery (Netflix Eureka Server):
3. Config Server
4. Communication Client
5. Admin Dashboard (Actuator)
6. ELK (Elasticsearch Logstash Kibana)
7. Distributed Tracking (Zipkin Server, Sleuth)
8. Continuous Data Flow (Message Queue): [Apache Kafka]
Swiggy Tracking, Ola/Uber cab status …. etc.
9. Circuit Breaker
10. API Gateway
SPRING CLOUD
Register and Discovery Server [Eureka Discovery Server]
- Register is a Storage Area for Audit details of all services
- It provides the details of all the services which are registered with Service
Registry.
- Spring Cloud + Netflix, provided one Register and Discovery Server "Eureka
Server".
- All MS application implemented using Spring ReST and also with Eureka client +
register=true/fetch=true value for register with Eureka server.
Register stores all services (MS) details, like: ServiceName, InstanceId, IP, PORT, Load
Details (no. of Instances… etc.).
Example:
+----------------------------------- EXAMPLE REGISTER -----------------------------+
| ServiceId InstanceId IP Port no. Load Factor |
+--------------------------------------------------------------------------------------------+
| CART-SER CART-SER-5410 192.168.0.1 8061 0/200 |
| CART-SER CART-SER-5411 192.168.0.2 8061 0/200 |
| PYMT-SER PYMT-SER-5412 192.168.1.4 8161 0/200 |
+---------------------------------------------------------------------------------------------+
Here,
- Above Register one ServiceInstance means one Line. So, register is a list of Service
Instances i.e. List<ServiceInstance>.
- ServiceId = application-name
- InstanceId = (application-name:randome value)
- Load Factor = Current No. of Request / total Request Capacity
----------------------------------------
Spring Cloud Vs Spring Boot?
----------------------------------------
- Spring Boot
Spring Boot mainly used for Webapps (Web MVC, REST), DATA JPA, Email,
Security, Configurations... etc.
- Spring Cloud
SPRING CLOUD
Spring Cloud is built on-top of Spring Boot. Spring cloud used to develop
microservices architecture-based Application by using tools like Register &
Discovery Server, Config Server, Gateway... etc.
------------
Task #01
------------
1. Create one Eureka Server
2. Define one MS# application
3. Register MS# with Eureka Server
---------------------------------------
Step to Create Eureka server
---------------------------------------
1. ApplicationName: SpringCloudEurekaServer
2. Add dependency: Eureka server
3. Add Annotation: “@EnableEurakaServer” on main/stater class.
4. In .properties file
eureka.client.register-with-eureka=false // DISABLE SELF REGISTER
eureka.client.fetach-registry=false // DISABLE SELF REGISTER
server.port = 8761 (default)
Note:
- To register with eureka every MS# need key-value “eureka.client.register-with-
eureka=true” and “eureka.client.fetach-registry=false” in .properties file. Spring
Cloud is a Parent for all MS# even for Eureka Server. It has given those common
keys-values for all child: (as default). So if we do not provide those keys-values
in .properties file for MS#, All MS# will by default register with eureka server.
- But Eureka Server even gets same true value. Which means “Eureka Server
Register with Eureka Server" So, to disable self-register we are using:
“eureka.client.register-with-eureka=false” at Eureka Server.
------------------------------
Step to code MS# app
------------------------------
Create one ReST Application register with Eureka Server.
1. ApplicationName: SpringCloud-CartServiceAPI
2. Add dependencies
Spring Web
Eureka discovery client
3. Add Annotation: “@EnableDiscoveryClient” on main/stater class.
4. In .properties file
Provide eureka server location-
eureka.client.service-url.defaultZone= http://localhost:8761/eureka
To register with eureka
eureka.client.register-with-eureka = true
Enable Fetching other MS# details
eureka.client.fetch-registry= true
Provide ReST API name
spring.application-name = CartServiceAPI
Provide Server port
Server.port = 8181
--------------------------------------
Application Execution Order
--------------------------------------
1. Run Eureka Server
2. Run MS# application
3. Enter URL: http://localhost:8761
4. Check Instance Running and click on Link (then modify)
Example: http://localhost:8181/v1/api/cart/show
SPRING CLOUD
Microservices Communication
- If one MS# wants to send request and get response from another MS# then it is
called as MS# communication.
- Internally all MS# are Spring Boot REST apps. So, we can use RestTemplate. But
hardcoding URL of MS# is not a good approach.
- Why?
MS# instances may run at different systems (IP May be diff in Realtime)
MS# multiple instances may be created for LoadBalancing.
One MS#/ReST API communicate other MS#/ReST API using Client APIs or
communication API those are provided by Spring cloud.
Note: These client APIs will get dynamic ID address and port from Eureka Server.
---------------------
DiscoveryClient
---------------------
- This is given by Spring Cloud to fetch details from Register server of a given MS#
based on ServiceId (application name) of client MS#.
- The result of DiscoveryClient is List<ServiceInstance>
Example:
List<ServiceInstance> serviceInstanceList = client.getInstances("CART-API");
- Here, if Client MS# is running only once, then result is List<SI> with only one
object(index#0)
- From Index#0 we read SI(ServiceInstance) and read URI (IP+PORT) finally create
URL by adding path (fixed always in code)
------------
Task #02
------------
1. Create one Eureka Server (Task#01)
SPRING CLOUD
2. Define one MS# application and register MS# with Eureka Server (Task#01)
3. Define on Consumer Application and register consumer app with Eureka Server.
--------------------------------------
Step to code consumer app
--------------------------------------
Create one ReST Application register with Eureka Server.
1. ApplicationName: SpringCloud-PaymentServiceAPI
2. Add dependencies
Spring Web
Eureka discovery client
3. Add Annotation: “@EnableDiscoveryClient” on main/stater class.
4. In .properties file (same as above)
Example:
1. @Component
2. public class CartConsumer {
3.
4. //Impl class is : EurekaDiscoveryClient -- given by Netflix Eureka
5. @Autowired
6. private DiscoveryClient client;
7.
8. public String getCartResponse() {
9. // Goto Eureka server with serviceId
10. List<ServiceInstance> list = client.getInstances("CART-SERVICE");
11.
12. // read at index#0 ==> returns SI
13. ServiceInstance si = list.get(0);
14.
15. // read URI
16. URI uri = si.getUri();
17.
18. // add path ==> return URL
19. String url = uri + "/cart/info";
20.
21. // use RestTemplate and call
22. RestTemplate rt = new RestTemplate();
23.
24. //make HTTP Request and get response
25. ResponseEntity<String> response = rt.getForEntity(url, String.class);
26.
27. //return response body
28. return response.getBody();
29. }
30. }
In above case, if Consumer wants to read one instance using DiscoveryClient that is not
possible, because it returns List<ServiceInstance>. And manually choose URI like
instance.get(0) or instance.get(1).
SPRING CLOUD
---------------------------
LoadBalancerClient
---------------------------
- To work with multiple instances of Producer MS# or ReST API
- LoadBalancerClient(I) will get only one Instance from Eureka Server that has less
Load Factor (it internally follows round robin concept)
Note: If you want run your MS# application as multiple instances then must provide:
eureka.instance.instance-id= {application-name} + {RandomValue}
------------
Task #03
------------
1. Create one Eureka Server (Task#01)
2. Define one MS# application (Task#01)
3. Register MS# with Eureka Server (Task#01)
4. Define on Consumer Application and register consumer app with Eureka Server.
--------------------------------------
Step to code consumer app
--------------------------------------
Create one ReST Application register with Eureka Server.
1. ApplicationName: SpringCloud-PaymentServiceAPI
2. Add dependencies
Spring Web
Cloud LoadBalancer
Eureka discovery client
3. Add Annotation: “@EnableDiscoveryClient” on main/stater class.
4. In .properties file
Provide eureka server location- (optional)
eureka.client.service-url.defaultZone= http://localhost:8761/eureka
To register with eureka (optional)
eureka.client.register-with-eureka = true
Enable Fetching other MS# details (optional)
eureka.client.fetch-registry= true
Provide ReST API name
spring.application-name = PaymentServiceAPI
SPRING CLOUD
Provide Server port
Server.port = 8282
*****************
LoadBalancer code:
*****************
1. @Component
2. public class CartConsumer {
3.
4. @Autowired
5. private LoadBalancerClient client;
6.
7. public String getCartServiceInstance() {
8.
9. ServiceInstance serviceInstance = client.choose("CART-API");
10. URI uri = serviceInstance.getUri();
11. String url = uri+"/cart/item";
12.
13. RestTemplate rt = new RestTemplate();
14. ResponseEntity<String> reponse = rt.getForEntity(url, String.class);
15. return reponse.getBody();
16. }
17. }
----------------
FeignClient
----------------
- Feign Client is also called as Open Feign. It is 3rd party API, integrated with Spring
Cloud used to inter-service communication.
- It generates code at runtime (Dynamic Proxy class) which internally uses
LoadBalancerClient code.
- Here, we need not to use any RestTemplate.
------------
Task #04
------------
1. Create one Eureka Server (Task#01)
2. Define one MS# application and register MS# with Eureka Server (Task#01)
3. Define on Consumer Application and register consumer app with Eureka Server.
--------------------------------------
Step to code consumer app
--------------------------------------
Create one ReST Application register with Eureka Server.
1. ApplicationName: SpringCloud-PaymentServiceAPI
SPRING CLOUD
2. Add dependencies
Spring Web
Open Feign
Eureka discovery client
3. Add Annotation: “@EnableDiscoveryClient” and “@EnableFeignClients”on
main/stater class.
4. In .properties file
Provide eureka server location- (optional)
eureka.client.service-url.defaultZone= http://localhost:8761/eureka
To register with eureka (optional)
eureka.client.register-with-eureka = true
Enable Fetching other MS# details (optional)
eureka.client.fetch-registry= true
Provide ReST API name
spring.application-name = PaymentServiceAPI
Provide Server port
Server.port = 8282
Config Server
- To externalize/separate all duplicate key=value pairs from each MS# into one
common location (Ex: GitHub) and connect with every MS# at runtime using a
medium server i.e. config server.
SPRING CLOUD
(Or)
To separate our configuration properties file from our MS applications using
config server.
- Config Server recommended port number is 8888.
- Config server will load all key-value pairs into Environment(I) memory from
GitHub repository or where our externalized configuration file is present.
Benefit:
- No need to write any duplicate key-value pairs in our MS application .properties
file.
------------
Task #05
------------
1. Create one configuration .properties file into GitHub repository
2. Create one Config server and link with GitHub repository
3. Define one MS# application and connect with config server
-------------------
GitHub Setup
--------------------
1. Create a new repository with the same name of our application (Recommended)
SPRING CLOUD
2. Create one file with name application.properties (or) application.yml and define
key-value pairs.
3. Share the repository link, username, password and branch name.
------------------------------------
Step to code config server
------------------------------------
1. ApplicationName: SpringCloud-ConfigServer
2. Add dependencies
Config Server
3. Add Annotation: “@EnableConfigServer” on top of the starter class.
4. In .properties file-
To link with GitHub repository
spring.cloud.config.server.git.uri = repositoryLink
spring.cloud.config.server.git.username = username
spring.cloud.config.server.git.password = password
spring.cloud.config.server.git.default-label = branchName
server.port = 8888
--------------------------------------
Step to code MS application
--------------------------------------
1. ApplicationName: SpringCloud-MyAppService
2. Add dependencies
Config Client
3. In .properties file-
To link with config server
spring.config.import=optional:configserver:http://localhost:8888
server.port = 8185
spring.application.name=MyApp-API
--------------------------------------
Application Execution Order
--------------------------------------
1. Run config Server
2. Enter url: http://localhost:8888/actuator/refresh
3. Run MS# application
4. Enter URL: http://localhost:8185/myapp/name (Example)
--------------------
Refresh Scope
--------------------
SPRING CLOUD
- Problem Statement: After starting our MS# application and we modify config
server data that is external properties file. It will not affect to our MS# application
until we restart our MS# application. But I do not want to restart our MS#
application. Without restarting I want to changes this data in our MS# application.
- Solution:
We have to implement "Refresh Scope" at MS# app. So, that if any
key=value is updated at Config server that will be updated at MS# app also,
without restarting MS# apps.
------------------------------
Coding Step only MS#
------------------------------
1. ApplicationName: SpringCloud-MyAppService
2. Add dependencies
Spring Web
Config Client
String boot actuator
3. In .properties file-
To link with config server
spring.config.import=optional:configserver:http://localhost:8888
To active actuator all endpoints
Management.endpoints.web.exposure.include=*
server.port = 8185
spring.application.name=MyApp-API
4. Add Annotation: “@RefreshScope” on top of RestController class for a particular
class or add top of the starter class for all rest controller.
--------------------------------------
Application Execution Order
--------------------------------------
1. Run config Server
2. Enter url: http://localhost:8888/actuator/refresh
3. Run MS# application
4. Enter URL: http://localhost:8185/myapp/name (Example)
5. Change config properties file data at GitHub repository
6. Send request http://localhost:MS#sidePort/actuator/refresh using postman.
(Manual process)
7. Then refresh MS# app URL http://localhost:8185/myapp/name
SPRING CLOUD
Above manual Postman call we can automate by implement using RestTemplate with
one
Scheduler Service that gets latest data always after 10s or 20s… what we want.
----------------
Coding Step
----------------
1. ApplicationName: SpringCloud-MySchedulerApp
2. Add dependencies
Spring Web
3. Add Annotation: @EnableScheduling on top of the Starter class.
4. Define One class:
Class Name: “FetchLatestData” and add “@Component” annotation on top
of that class.
Define one Method: fetchingData() and add “@Scheduled( cron= “10 * * *
* *”)” annotation on top of this method.
Note: if same keys are available at GitHub repository(Config server) and #MS application
then priority is given to GitHub repository(Config server) properties file key=value only.
Actuator:
- It is Monitoring and managing some pre-defined services which are commonly
used in Production Environment for every MS# apps. Like: Health Checking,
Beans details, mapping information (URL, HttpMethods), cache, heap, thread
dumps… etc.
-----------------
Step to code
-----------------
1. ApplicationName: SpringCloud-MyRestAPI
2. Add dependencies
Spring Web
String boot actuator
3. In .properties file-
Management.endpoints.web.exposure.include=*
Management.endpoints.web.exposure.include= health,beans,env
Note: If we did not specify any include services then default only one service 'health' is
activated. (old versions: Up to 2.4.x -- 2 were activated - health, info)
--------------------------------------
Application Execution Order
--------------------------------------
1. Run MS# application
2. For actuator endpoints details enter URL: http://localhost:8181/actuator
3. For Our MS# application: http://localhost:8181/path
Drawbacks:
- If we use only 'Actuator' that is monitoring and managing individual API. If our
application has multiple API then individually each API monitoring and managing
very difficult. Also using Actuator, we can check services manually.
------------
Task #05
------------
1. Create one Admin server
2. Define one MS# application
----------------------------------------
Coding Step for Admin server
----------------------------------------
1. Application name: SpringCloud-AdminServer
2. Add Dependence:
Codecentric’s Spring Boot Admin Server
Where codecentric’s is provider name
3. Add Annotation: “@EnableAdminServer” on top of the starter class.
4. In properties file:
Server.port=9999
--------------------------------------------
Coding Step for MS# application
--------------------------------------------
5. Application name: SpringCloud-MyAppWithAdminClient
6. Add Dependence:
Codecentric’s Spring Boot Admin client
Spring boot actuator
Spring Web
7. Add Annotation: “@EnableAdminServer” on top of the starter class.
8. In properties file:
Active actuator endpoints
management.endpoints.web.exposure.include=*
Connect with Admin Server
spring.boot.admin.client.url=http://localhost:9999
SPRING CLOUD
--------------------------------------
Application Execution Order
--------------------------------------
1. Run Admin server
2. Enter URL for admin Dashboard: http://localhost:9999
3. Run MS# application
4. For Our MS# application: http://localhost:port/path
- Spring Cloud: Register & Discovery Server, Config Server, Gateway… etc.
Q) What is a Register and Discovery Server? Give Example? How it is different from
webserver(tomcat)?
Answer:
- Register: It will store all MS# instance details in ServiceInstance format.
1 ServiceInstance = 1 ServiceId + 1 InstanceId + 1 IP + 1 PORT + 1 LF (data)
- Discovery: It will find to get another MS# details from Register to communicate
with that MS#.
- Register and Discovery Server example: Netflix Eureka Server, Apache Zookeeper.
- Webservers are used to run .war files. (webapps) but Register and Discovery
Server for MS# apps.
SPRING CLOUD
Q) What is the defaultZone value if we did not provide in MS#?
Answer: EurekaClientConfigBean is given by Spring Cloud. That is storing config details
for location of Eureka as a Map. The default URL is given as:
http://localhost:8761/eureka
Q) Why DiscoveryClient?
Answer: TO get MS# details from Eureka Server at runtime. Based on MS# serviceId
Q) What is ServiceInstance?
Answer: ServiceInstance means details of One MS# instance. ServiceInstance =
serviceId+ InstanceId + URI(IP/PORT) + ...
Q) How many Instances does it return for a single request from eureka?
Answer: Alway one ServiceInstance which has Less Load Factor.
SPRING CLOUD
Q) Do we need RestTemplate also if we use LoadBalancerClient?
Answer: Yes, RestTemplate is Required. Because LoadBalancerClient interacts with
Eureka. LoadBalancerClient will not make any HTTP Request to REST/MS# apps.