Microservices Notes
Microservices Notes
Microservices
==============
Advantages
----------
1) Simple to develop
Dis-Advantages
--------------
1) Difficult to maintain
Advantages
----------
1) Loosely Coupling
2) Easy To maintain
3) Faster Development
4) Quick Deployment
5) Faster Releases
6) Less Downtime
Dis-Advantages
--------------
2) Lot of configurations
3) Visibility
4) Pack of cards
===========================
Microservices Architecture
===========================
4) API Gateway
5) Admin Server
6) Zipkin
Service Registry
++++++++++++++++
-> Service Registry acts as DB of services available in the project
-> It provides the details of all the services which are registered with
Service Registry
-> We can identify how many services available in the project
-> We can identify how many instances available for each service
-> We can use "Eureka Server" as service registry
-> Eureka Server provided by "Spring Cloud Netflix" library
Services
+++++++++
-> Services means REST APIs / Microservices
-> Services contains backend business logic
-> In the project, some services will interact with DB
-> In the project, some services will interact with third party REST API
( external communication )
-> In the project, some services will interact with another services with
in the project
( inter-service communication )
-> For inter-service communication we will use feign-client
-> To distribute the load, we can run one service with Multiple Instances
(Load Balancing)
API Gateway
+++++++++++
-> API Gateway is used to manage our backend apis of the project
-> API Gateway acts as mediator between end users and backend apis
-> API Gateway can contain filter logic to decide request processing
(Authentication)
-> API Gateway will contain Routing logic (which request should go to
which REST API)
-> API Gateway also will be registered with Service Registry
-> Spring Cloud Gateway we can use as API Gateway
Admin Server
------------
-> Admin Server is used to manage all backend apis actuator endpoints at
one place
-> Our backend apis will be registered with Admin Server
-> Admin Server will provide User interface to monitor apis actuator
endpoints
Zipin Server
---------------
-> Zipkin Server is used for Distributed Tracing
-> Using this Zipkin, we can monitor which API is taking more time to
process our request.
=============================================================
Mini Project Implementation using Microservices Architecture
=============================================================
Sample Data
------------
TCS-3000
HCL-1500
AXIS-1200
===============================================================
Steps to develop Service Registry Application (Eureka Server)
===============================================================
1) Create Service Registry application with below dependency
- EurekaServer (spring-cloud-starter-netflix-eureka-server)
server:
port: 8761
eureka:
client:
register-with-eureka: false
URL : http://localhost:8761/
- eureka-discovery-client
- starter-web
- starter-datajpa
- h2
- devtools
server-port
h2-datasource-properties
application-name
-----------------------------------application.yml-----------------------
------------------
server:
port: 1111
spring:
application:
name: STOCK-PRICE-API
datasource:
username: sa
password: sa
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
jpa:
defer-datasource-initialization: true
-------------------------------------------------------------------------
-------------------------
4) Create Entity class & Repository interface for COMPANY STOCK PRICE
DETAILS
7) Run the application and check in Eureka Dashboard (It should display
in eureka dashboard)
- web-starter
- devtools
- eureka-discovery-client
- fegin-client
-------------------------------------------------------------------------
--------------------------------
@RestController
public class StockCalcRestController {
@GetMapping("/calc/{cname}/{qty}")
public ResponseEntity<String> calculate(@PathVariable String cname,
@PathVariable Integer qty) {
-------------------------------------------------------------------------
----------------------------------
-> Using FeginClient we can make rest call to another service using name
of the service (no need of url)
-------------------------------------------------------------------------
-------------------------------------
@FeignClient(name = "STOCK-PRICE-API")
public interface StockPriceClient {
@GetMapping("/price/{cname}")
public StockPrice invokeStockPrice(@PathVariable String cname);
}
-------------------------------------------------------------------------
------------------------------------
Note : Write @EnableFeignClients annotation at boot start class
-------------------------------------------------------------------------
------------------------------------
@RestController
public class StockCalcRestController {
@Autowired
private StockPriceClient priceClient;
@GetMapping("/calc/{cname}/{qty}")
public ResponseEntity<String> calculate(@PathVariable String cname,
@PathVariable Integer qty) {
-Dserver.port=port-number
-------------------------------------------------------------------------
-------------------------------------
API Gateway
-------------------------------------------------------------------------
------------------------------------
-> API Gateway will act as mediator between client requests & backend
apis
-> API Gateway will provide single entrypoint to access our backend apis
1) Filters
2) Routing
-> Filters are used to execute some logic before request processing and
after request processing
-> Routing is used to tell which request should go to which REST API
@EnableZuulProxy
@EnableDiscoveryClient
application.yml file
+++++++++++++++++++++++
server:
port: 3333
spring:
application:
name: API-GATEWAY
zuul:
routes:
api1:
path: /stock/v1/**
service-id: STOCK-PRICE-API
api2:
path: /stock/v2/**
service-id: STOCK-CALC-API
-------------------------------------------------------------------------
-------------------------------------
-> We are running Service Registry project with Eureka Server on 8761
port number
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9090/eureka
-------------------------------------------------------------------------
-------------------------------------
Working with Spring Cloud API Gateway
-------------------------------------------------------------------------
------------------------------------
-> web-stater
-> eureka-client
-> cloud-gateway
-> devtools
----------------------------------------application.yml file-------------
----------------------------------
spring:
cloud:
gateway:
discovery.locator:
enabled: true
lowerCaseServiceId: true
routes:
- id: stock-price-api
uri: lb://STOCK-PRICE-API
predicates:
- Path=/price/{companyName}
- id: stock-calc-api
uri: lb://STOCK-CALC-API
predicates:
- Path=/calc/{companyName}/{qty}
application:
name: CLOUD-API-GATEWAY
server:
port: 3333
-------------------------------------------------------------------------
-----------------------------------
2) Predicate
3) Filters
-> Filters are used to manipulate incoming request and outgoing response
of our application
Note: Using Filters we can implement security also for our application.
-------------------------------------------------------------------------
-------------------------------------
@Component
public class MyPreFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
keySet.forEach(key -> {
List<String> values = headers.get(key);
System.out.println(key +" :: "+values);
});
return chain.filter(exchange);
}
}
-------------------------------------------------------------------------
---------------------------
@Component
public class MyPostFilter implements GlobalFilter {
}
-------------------------------------------------------------------------
---------------------------------
-> We can validate client given token in the request using Filter for
security purpose
-> Filters are used to manipulate request & response of our application
===========================================
Spring Boot Admin Server and Admin Client
============================================
-> Admin server will provide user interface to monitor and manage all the
apis actuator endpoints
-> The REST APIs of our application should register with admin server (It
is called as Admin client)
Note: Using this approach we can monitor all the apis at one place
4) Access application URL in browser (We can see Admin Server UI)
a) starter-web
b) starter-actuator
c) admin-starter-client
d) devtools
a) server-port
b) application-name
c) enable-actuator-endpoints
d) configure admin serve URL to reiger
----------------------------------application.yml------------------------
-------------
server:
port: 1111
spring:
application:
name: CLIENT-ONE
boot:
admin:
client:
url: http://localhost:8080/
management:
endpoints:
web:
exposure:
include: '*'
-------------------------------------------------------------------------
------
=================================
Working with Mono & Flux Objects
=================================
-> Mono & Flux objects are used to achieve reactive programming
-> To work with reactive programming Spring Boot provided below starter
'spring-boot-starter-webflux'
}
-------------------------------RestController----------------------------
--------------------
@RestController
public class CustomerRestController {
@GetMapping("/event")
public Mono<CustomerEvent> getCustomerEvent() {
return mono;
}
=================================
Circuit Breaker
=================================
-> Fault-tolerance system means when main logic is failed to execute then
we should execute fallback logic to process client request
===========
Usecase
===========
=> Get data from redis, if redis logic is failing then we should get data
from database
<dependency>
<groupId>io.pivotal.spring.cloud</groupId>
<artifactId>spring-cloud-services-starter-circuit-
breaker</artifactId>
</dependency>
-------------------------------------------------------------------------
-----------------------
@RestController
public class DataRestController {
@GetMapping("/data")
@HystrixCommand(
fallbackMethod = "getDataFromDB",
commandProperties = {
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",
value="3"),
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",
value="10000"),
@HystrixProperty(name="circuitBreaker.enabled", value="true")
}
)
public String getDataFromRedis() {
System.out.println("**getDataFromRedis() method called**");
if (new Random().nextInt(10) <= 10) {
throw new RuntimeException("Redis Server Is Down");
}
// logic to access data from redis
return "data accessed from redis (main logic) ....";
}
=================================
Sleuth & Zipkin
=================================
-> As part of application execution one Rest API can communicate another
REST API
-> When we send request from UI, it will process by Multiple REST APIs
with Interservice communication
*** How we can understand which rest api is taking more time to process
request ? ***
-> If we add Sleuth dependency in REST API then it will add span-id and
trace-id for log messages
-> If one request is processing multiple REST API then Sleuth will use
same span-id for REST APIs to generate log message
-> By using span-id and trace-id we can understand which REST api has
taken more time process request
-> To monitor span-id and trace-id details we will use ZipKin server
-> Zipkin server is providing user interface (UI) to monitor all the
details
Note: The REST APIs which are having sleuth dependency should register
with Zipkin server
a) web-starter
b) sleuth
c) zipkin
d) devtools
( URL : http://localhost:9411 )
-------------------------------------------------------------------------
-------------------------