============== Microservices ============== 1) Monolith Architecture 2) Drawbacks of Monolithic 3) Microservices Architecture 4) Pros & Cons with Microservices 5) Service Registry (Eureka) 6) Admin Server 7) Zipkin Server 8) FeignClient (Interservice Comm) 9) Load Balancer (Ribbon) 10) API Gateway (Filters + Routing) 11) Config Server 12) Circuit Breaker (Resillence4J) ====================== Monolith Architecture ====================== => Developing all functionalities in single application. 1) Presentation Layer 2) Business Layer 3) Data Access Layer => Drawbacks with Monolith Architecture 1) Burden on server 2) Response Dealy 3) Single Point of failure 4) Technology Dependent 5) Re-Deploy entire app => To overcome problems of Monolith Architecture, people are using Microservices Architecture. =============== Microservices =============== => It is not a new technology => It is not a framework => It is not a library => It is an architectural design pattern. => It is universal and anyone can use this architecture to develop applications. Note: The main aim of microservices design pattern is to develop application functionalities with loosely coupling. ============================== Advantages with Microservices ============================== 1) Loosely Coupled 2) Burden Reduced on Servers 3) Easy Maintence 4) No Single point of failure 5) Technology Independent 6) Quick deliveries ============================== Challenges with Microservices ============================== 1) Bounded Context 2) Repeated Configurations 3) Visibility => Bounded context means identifying how many microservices we need to develop for one application and deciding which functionality we need to add in which microservice. => In Several microserices we need to write same configurations like data source, smtp, kafka, redis etc. => In microservice architecture we might not get chance to work with all apis available in the application. ================================= Spring Cloud with Microservices ================================= 1) Service Registry (Eureka) 2) Admin Server 3) Zipkin Server 4) Config Server 5) Kafka Server 6) Redis Server 7) API Gateway 8) FeignClient (Interservice communication) ================== Service Registry ================== => It is also called as Service Discovery or Discovery server. => Service Registry is used to maintain all Microservices (apis) information at one place. => Using service registry we can access below details of all microservices with UI. 1) name 2) status 3) url 4) no.of instances => It will provide user interface to get Microservices information. => We can use Eureka Server as service registry. Note: Eureka Server provided by Spring Cloud Libraries. ============= Admin Server ============= => It is used to monitor and manage all the apis at one place. => It provides beautiful user interface to access all apis actuator endpoints at one place. Ex: health, info, beans, url-mappings, env, loggers, thread dump, heap dump... ============== Zipkin Server ============== => It is used for distributed tracing of our requests. ex: 1) Which request processed by which microservice 2) Time taken by microservice to process a request 3) Which microservices involved in request processing => It provides beautiful user interface to trace microservices request processing details. ================ Config Server ================ => It is used to externalize config props of our application. Note: Instead of keeping properties (datasource, smtp, kafka, redis...) in our application we can load them from git repo by using config server. => Config Server makes our application loosely coupled with properties file or yml file. ============ FeignClient ============ => It is used for interservice communication. => If one api communicate with another api with in the same application then it is called as Inter service communication. Note: FeignClient will provide Load Balancer support internally. ============== Kafka Server ============== => It is used as message broker => Distributed streaming platform => It is used to process realtime data feeds => It works based on publisher-subscriber model =============== Redis Server =============== => Redis is a cache server => Redis we can use as in memory database => Redis represents data in key-value format => Redis is used to reduce no.of db calls and improve performance of the application. ============= API Gateway ============= => It acts as Entry point for all backend apis. => It acts as mediator between frontend app and backend apis. => In API Gateway we will write filters + Routings Filter : We can perform request pre processing and post processing Ex: validate request Routing : Forward the request to actual backend api. Ex: /order : ORDER_REST_API /product : PRODUCT_REST_API =============================================================== Steps to develop Service Registry Application (Eureka Server) =============================================================== 1) Create SpringBoot application with below dependency - Eureka Server (spring-cloud-starter-netflix-eureka-server) - devtools 2) Configure @EnableEurekaServer annotation in boot start class 3) Configure below properties in application.yml file ``` spring: application: name: 22-Eureka-Server server: port: 8761 eureka: client: register-with-eureka: false ``` Note-1: If "Service-Registry" project port is 8761 then clients can discover service-registry and will register automatically with service-registry. Note-2 : If service-registry project running on any other port number then we have to register clients with service-registry manually. 4) Once application started we can access Eureka Dashboard using below URL URL : http://localhost:8761/ ====================================== Steps to develop Spring Admin-Server ====================================== 1) Create Boot application with "admin-server" dependency (select it while creating the project) 2) Configure @EnableAdminServer annotation at start class 3) Change Port Number (Optional) spring: application: name: 02_Admin_Server server: port: 1111 4) Run the boot application 5) Access application URL in browser (We can see Admin Server UI) URL : http://localhost:1111/ ================================== Steps to work with Zipkin Server ================================== 1) Download Zipin Jar file URL : https://zipkin.io/pages/quickstart.html 2) open cmd and execute zipkin jar file with below command $ java -jar 3) Zipkin Server Runs on Port Number 9411 4) Access zipkin server dashboard URL : http://localhost:9411/ ============================= Steps to develop WELCOME-API ============================= 1) Create Spring Boot application with below dependencies - starter-web - actuator - devtools - eureka-discovery-client - admin-client - zipkin 2) Configure @EnableDiscoveryClient annotation at boot start class. 3) Create RestController with required method ``` @RestController public class WelcomeRestController { @GetMapping("/welcome") public String getWelcomeMsg() { String msg = "Welcome To Ashok IT..!!"; return msg; } } ``` 4) Configure below properties in application.yml file ``` spring: application: name: 24-Welcome-API boot: admin: client: url: http://localhost:1111/ server: port: 8081 management: endpoints: web: exposure: include: '*' ``` 5) Run the application and check in Eureka Dashboard (It should display in eureka dashboard) 6) Check Admin Server Dashboard (It should display) (we can access application details from here) Ex: Beans, loggers, heap dump, thred dump, metrics, mappings etc... 7) Send Request to REST API method 8) Check Zipkin Server UI and click on Run Query button (it will display trace-id with details) =============================== Steps to develop GREET-API =============================== 1) Create Spring Boot application with below dependencies - starter-web - actuator - devtools - eureka-discovery-client - admin-client - zipkin - open feign 2) Configure @EnableDiscoveryClient annotation at boot start class. 3) Create RestController with required method @RestController public class GreetRestController { @GetMapping("/greet") public String getGreetMsg() { String msg = "Good Morning"; return msg; } } 4) Configure below properties in application.yml file ``` spring: application: name: 25-Greet-API boot: admin: client: url: http://localhost:1111/ server: port: 8081 management: endpoints: web: exposure: include: '*' ``` 5) Run the application and check in Eureka Dashboard (It should display in eureka dashboard) 6) Check Admin Server Dashboard (It should display) (we can access application details from here) Ex: Beans, loggers, heap dump, thred dump, metrics, mappings etc... 7) Send Request to REST API method 8) Check Zipkin Server UI and click on Run Query button (it will display trace-id with details) ============================== Interservice communication ============================== => With in the application if one microservice is communicating with another microservice then it is called as Interservice communication. => We will use @FeignClient for interservice communication. => When we use FeignClient no need to configure service URL for the communication. => With service-name feign client can fetch service url from service registry for inter service communication. => Add @EnableFeignClients dependency in GREET-API boot start class. => Create FeignClient interface like below ``` @FeignClient(name="24-WELCOME-API") public interface WelcomeApiClient { @GetMapping("/welcome") public String invokeWelcomeApi(); } ``` => Inject feign client into GreetRestController like below ``` @RestController public class GreetRestController { @Autowired private WelcomeApiClient welcomeApiClient; @GetMapping("/greet") public String getGreetMsg() { String welcomeApiResponse = welcomeApiClient.invokeWelcomeApi(); String greetApiResponse = "Good Morning"; return greetApiResponse + ", " + welcomeApiResponse; } } ``` => Run the applications and access greet-api method (It should give combined response) ================== Load Balancing ================== => If we run our application in one server then burden will be increased on that server. 1) Single Server should handle all the load 2) Burden on server 3) Response delay 4) Server can crash 5) Single Point of failure => To overcome above problems we will run our application in multiple servers so that we can distribute the requests to multiple servers. => Load Balancer is used to distribute requests to multiple servers. => We have below advantages with load balancer 1) Requests will be distributed to multiple servers 2) Less Burden on server 3) Quick Responses to clients 4) High Availability =============================== Load Balancing For Welcome API =============================== 1) Remove server port number from welcome api yml file 2) Make changes in rest controller to send port number in response. ``` @RestController public class WelcomeRestController { @Autowired private Environment env; @GetMapping("/welcome") public String getWelcomeMsg() { String port = env.getProperty("server.port"); String msg = "Welcome To Ashok IT..!! (" + port + ")"; return msg; } } ``` 3) Right click => Run as => run configuration => select welcome-api => VM Arguments => -Dserver.port=8081 and apply and run it. 4) Right click => Run as => run configuration => select welcome-api => VM Arguments => -Dserver.port=8082 and apply and run it. 5) Right click => Run as => run configuration => select welcome-api => VM Arguments => -Dserver.port=8083 and apply and run it. Note: With this our api will run in 3 servers with 3 diff port numbers. 6) Check Eureka Dashboard and observer 3 instances available for welcome-service or not. 7) Start Greet-Service and send request to Greet-Service and check Interservice communication. ======================================== Working with Spring Cloud API Gateway ======================================== 1) Create Spring boot application with below dependencies -> eureka-client -> cloud-reactive-gateway -> devtools 2) Configure @EnableDiscoveryClient annotation at boot start class 3) Configure API Gateway Routings in application.yml file like below ``` spring: application: name: 26-Api-Gateway cloud: gateway: server: webflux: routes: - id: api-1 uri: lb://24-Welcome-API predicates: - Path=/welcome - id: api-2 uri: lb://25-Greet-API predicates: - Path=/greet server: port: 3333 ``` 4) Create Filter to validate incoming request if request contains below header then it is valid request so we can process it. Secret=ashokit@123 if above header is not present then it is invalid request, don't process it. ``` @Component public class RequestValidateFilter implements GlobalFilter { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println(" filter() - executed..... "); // read request headers ServerHttpRequest request = exchange.getRequest(); HttpHeaders headers = request.getHeaders(); Set keySet = headers.keySet(); if(!keySet.contains("Secret")) { throw new RuntimeException("Invalid Request"); } List list = headers.get("Secret"); if(!list.get(0).equals("ashokit@123")) { throw new RuntimeException("Invalid Request"); } return chain.filter(exchange); } } ``` ================================ What is Cloud Config Server ================================ => We are configuring our application config properties in application.properties or application.yml file. Ex: DB Props, SMTP props, Kafka Props, App Messages etc... => application.properties or application.yml file will be packaged along with our application (it will be part of our app jar file). => If we want to make any changes to properties then we have to re-package our application and we have to re-deploy our application. Note: If any changes required in config properties then We have to repeat the complete project build & deployment process which is time consuming. => To avoid this problem, we have to seperate our project source code and project config properties files. => To externalize config properties from the application we can use Spring Cloud Config Server. => Cloud Config Server is part of Spring Cloud Library. Note: Application config properties files we will maintain in git hub repo and config server will load them and will give to our application based on our application-name. App-name : flights ====> flights.yml App-name : hotels ====> hotels.yml App-name : trains ====> trains.yml => Our microservices will get config properties from Config server and config server will load them from git hub repo. ================================ Developing Config Server App ================================ @@ Step-1 :: Create Git Repository and keep ymls files required for microservices Note: We should keep file name as application name. app name : greet then file name : greet.yml app name : welcome then file name : welcome.yml ### Git Repo : https://github.com/ashokitschool/configuration_properties @@ Step-2 :: Create Spring Starter application with below dependencies 1) config server 2) devtools @@ Step-3 :: Write @EnableConfigServer annotation at boot start class @@ Step-4 :: Configure below properties in application.yml file ``` spring: application: name: 07_Cloud_Config_Server cloud: config: server: git: uri: https://github.com/ashokitschool/configuration_properties server: port: 9093 ``` ================================= Config Client Development ================================= 1) Create Spring Boot application with below dependencies a) web-starter b) config-client c) dev-tools d) actuators 2) Create Rest Controller with Required methods ``` @RestController public class MsgRestController { @Value("${msg}") private String msg; @GetMapping("/") public String getMsg() { return msg; } } ``` 3) Configure ConfigServer url in application.yml file like below ```` spring: application: name: welcome config: import: optional:configserver:http://localhost:9093 ``` ========================================================================= How to reload config properties dynamically without restarting servers ========================================================================= => We need to make below 3 changes in config-client app to reload latest config props -> configure @RefreshScope annotation at Rest controller class -> Enable actuator endpoint 'refresh' in application.yml ``` management: endpoints: web: exposure: include: refresh ``` -> Send post request to actuator endpoint 'refresh' from postman URL : http://localhost:8080/actuator/refresh -> After refresh, test your config client application ===============================================================================