Micro
Micro
txt
####################
Microservices
##################
================================
What is Monolith Architecture
================================
-> If we develop all the functionalities in single project then it is called as Monolith
architecture based application
-> As monolith application contains all functionalities, it will become fat jar/war
-------------
Advantages
-------------
1) Simple to develop
---------------
Dis-Advantages
----------------
1) Difficult to maintain
****** To overcome the problems of Monolithic, Microservices architecture came into market******
-> In Microservices architecture we don't develop all the functionalities in single project. We
will divide project functionalities into several REST APIs.
-> Microservices is not related to only java. Any programming language specific project can use
Microservices Architecture.
-------------
Advantages
-------------
1) Loosely Coupling
2) Easy To maintain
3) Faster Development
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 1/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
4) Quick Deployment
5) Faster Releases
6) Less Downtime
7) Technology Independence (We can develop backend apis with multiple technologies)
---------------
Dis-Advantages
----------------
2) Lot of configurations
3) Visibility
4) Pack of cards
===========================
Microservices Architecture
===========================
-> People are customizing microservices architecture according to their Project requirement
-> Most of the projects will use below components in 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
===================
Backend 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
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 2/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
( 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
=============
=============================================================
Mini Project Implementation using Microservices Architecture
=============================================================
Sample Data
------------
TCS-3000
HCL-1500
AXIS-1200
STOCK-PRICE-CALC-API : It is used to calculate total stocks cost based on company name and
quantity
Note: To calculate total stocks cost, STOCK-PRICE-CALC-API should get company stock price from
STOCK-PRICE-API (INTER SERVICE COMMUNICATION)
===============================================================
Steps to develop Service Registry Application (Eureka Server)
===============================================================
1) Create Service Registry application with below dependency
- EurekaServer (spring-cloud-starter-netflix-eureka-server)
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 3/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
server:
port: 8761
eureka:
client:
register-with-eureka: false
Note: If Service-Registry project port is 8761 then clients can discover service-registry and will
register automatically with service-registry. 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/
- 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
5) Create "data.sql" file under src/main/resource folder with insert queries to load data into db
table like below
INSERT INTO STOCK_PRICE_DTLS (STOCK_ID, COMPANY_NAME, COMPANY_PRICE) VALUES (101, 'TCS', 3000.00);
INSERT INTO STOCK_PRICE_DTLS (STOCK_ID, COMPANY_NAME, COMPANY_PRICE) VALUES (102, 'HCL', 1500.00);
INSERT INTO STOCK_PRICE_DTLS (STOCK_ID, COMPANY_NAME, COMPANY_PRICE) VALUES (103, 'HDFC',
4500.00);
INSERT INTO STOCK_PRICE_DTLS (STOCK_ID, COMPANY_NAME, COMPANY_PRICE) VALUES (104, 'SBI', 450.00);
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 4/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
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) {
--------------------------------------------------------------------------------------------------
---------
-> If STOCK-PRICE-API is running in Multiple instances for load balancing our calc-api should
access all the instances in round-robbin methodology
-> To overcome these problems we can use Interservice Communication using FeignClient
-> Using FeginClient we can make rest call to another service using name of the service (no need
of url)
-> FeginClient will get service URL from service-registry based on service-name
--------------------------------------------------------------------------------------------------
------------
@FeignClient(name = "STOCK-PRICE-API")
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 5/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
@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) {
Note: Run price-api with multiple instances using Run Configuration Option
-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
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 6/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
#####################################
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
--------------------------------------------------------------------------------------------------
----------
1) Route
2) Predicate
3) Filters
-> Routing is used to defined which request should be processed by which REST API in backend.
Routes will be configured using Predicate
-> Predicate : This is a Java 8 Function Predicate. The input type is a Spring Framework
ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or
parameters.
-> 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) {
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 7/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
keySet.forEach(key -> {
List<String> values = headers.get(key);
System.out.println(key +" :: "+values);
});
return chain.filter(exchange);
}
}
--------------------------------------------------------------------------------------------------
--
@Component
public class MyPostFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
}
--------------------------------------------------------------------------------------------------
--------
-> We can validate client given token in the request using Filter for security purpose
-> Filters are used to manipulate request & response of our application
-> Any cross-cutting logics like security, logging, moniroing can be implemented using Filters
===========================================
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
---------------------------
Working with Admin-Server
---------------------------
1) Create Boot application with admin-server dependency (select it while creating the project)
4) Access application URL in browser (We can see Admin Server UI)
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 8/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
---------------------------
Working with Admin-Client
---------------------------
1) Create Spring Boot application with below dependecies
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: '*'
-------------------------------------------------------------------------------
######################
Cloud Config Server
######################
-> We will maintain application configuration yml files in git hub repo.
-> Config Server application will connect with Git Hub repo to load all ymls
-> Our APIs (Microservices) will connect with config server to load yml data based on application
name.
Note: If we use config server then we no need to re-package our application when we make some
changes in properties.
==================
Config Server App
===================
1) Create Git Repository and keep ymls files required for projects
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 9/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
@SpringBootApplication
@EnableConfigServer
public class Application {
spring:
cloud:
config:
server:
git:
uri: https://github.com/ashokitschool/configuration_properties
clone-on-start: true
=================================
Config Server Client Development
=================================
a) web-starter
b) config-client
c) dev-tools
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
@RestController
public class WelcomeRestController {
@Value("${msg}")
private String msg;
@GetMapping("/")
public String getWelcomeMsg() {
return msg;
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 10/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
}
}
server:
port: 8081
spring:
config:
import: optional:configserver:http://localhost:8080
application:
name: greet
==================================================================================
============
Redis Cache
============
1) What is Cache ?
3) What is Redis ?
=> By using Cache data, we can reduce no.of db calls from our application.
Note: DB call is always costly (it will take more time to execute)
=> By using Cache data (Cache Memory) we can increase performance of the application.
##### Redis Cache is one of the most famous Cache available in Market #####
=> The open source, in-memory data store used by millions of developers as a database, cache,
streaming engine, and message broker.
=> Spring Boot provided below starter to communicate with Redis Server
put (...)
get(..)
entries (.)
delete(..)
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 11/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
Key-Value
KEY - EMP
101 - Raju
102 - Rani
KEY - BOOKS
103 - Java
KEY - CITIES
104 - Hyd
=================================
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'
-------------------------------Binding class-----------------------------------------------
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomerEvent {
}
-------------------------------RestController------------------------------------------------
@RestController
public class CustomerRestController {
@GetMapping("/event")
public Mono<CustomerEvent> getCustomerEvent() {
return mono;
}
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 12/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
============
Redis Cache
============
1) What is Cache ?
3) What is Redis ?
=> By using Cache data, we can reduce no.of db calls from our application.
Note: DB call is always costly (it will take more time to execute)
=> By using Cache data (Cache Memory) we can increase performance of the application.
##### Redis Cache is one of the most famous Cache available in Market #####
=> The open source, in-memory data store used by millions of developers as a database, cache,
streaming engine, and message broker.
=> Spring Boot provided below starter to communicate with Redis Server
put (...)
get(..)
entries (.)
deleet(..)
===================================
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 13/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
Link : https://www.mediafire.com/file/ul4aeeirc8nrs2a/Redis-x64-3.0.504.rar/file
-> Extract rar file and Run Redis-Server.exe and Run Redis-Client.exe
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
@Data
public class Country implements Serializable {
@Configuration
public class RedisConfig {
@Bean
public JedisConnectionFactory jedisConn() {
JedisConnectionFactory jedis = new JedisConnectionFactory();
// Redis server properties
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 14/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
return jedis;
}
@Bean
public RedisTemplate<String, Country> redisTemplate() {
RedisTemplate<String, Country> rt = new RedisTemplate<>();
rt.setConnectionFactory(jedisConn());
return rt;
}
}
@RestController
public class CountryRestController {
@PostMapping("/country")
public String addCountry(@RequestBody Country country) {
opsForHash.put("COUNTRIES", country.getSno(), country);
return "Country Added";
}
@GetMapping("/countries")
public Collection<Country> getCountries() {
Map<Integer, Country> entries = opsForHash.entries("COUNTRIES");
Collection<Country> values = entries.values();
return values;
}
{
"sno": 1,
"name": "India",
"countryCode": "+91"
}
======================================================================
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 15/16
6/6/23, 12:17 PM ashokitech.com/uploads/notes/320998504_1684914194.txt
https://ashokitech.com/uploads/notes/320998504_1684914194.txt 16/16