Master Microservices with Spring Boot and Spring Cloud
====================================================
·
Develop and design RESTful web services with
Spring Boot
·
Develop MICROSERVICES with Spring Boot and
Spring Cloud
·
Orchestrate microservices with KUBERNETES
·
Create containers for microservices with DOCKER
·
IMPLEMENT Exception Handling, Validation,
HATEOAS and filtering for RESTful Web Services.
·
Implement client-side load balancing (Ribbon),
Dynamic scaling(Eureka Naming Server) and an API Gateway (Zuul)
·
You will setup Centralized Microservices
Configuration with Spring Cloud Config Server
·
You will learn to implement Distributed tracing
for microservices with Spring Cloud Sleuth and Zipkin
·
You will implement Fault Tolerance for
microservices with Hystrix
·
You will understand how to version your RESTful
Web Services
·
You will understand how to monitor RESTful
Services with Spring Boot Actuator
·
You will understand how to document RESTful Web
Services with Swagger
·
You will understand the best practices in
designing RESTful web services
·
Using Spring Cloud Bus to exchange messages
about Configuration updates
·
Simplify communication with other Microservices
using Feign REST Client
Spring Boot Microservices and Spring Cloud
===============================================
What you'll learn
·
Build and run RESTful Microservices
·
Implement User Authentication
·
Eureka Discovery Service
·
Implement User Authorization with Spring
Security and JWT
·
Spring Cloud API Gateway
·
Learn to use JPA to persist data into a Database
·
Cloud Cloud Config Server
·
Learn to install MySQL Server and persist data
into MySQL
·
Spring Cloud Bus and Rabbit MQ
·
H2 in-memory database and H2 Console
·
Spring Boot Actuator
·
Learn to use HTTP Postman
·
Use Spring Security
·
Learn to use Spring Initializer
·
Distributed Tracing with Sleuth and Zipkin
·
Learn to use Spring Tool Suite
·
Centralized Logging with ELK Stack(Logstash,
Elasticsearch, Kibana)
OAuth 2.0 in Spring Boot Applications
=======================
What you'll learn
OAuth 2.0
OAuth 2 Authorization Flows
The New OAuth 2.0 stack in Spring Security 5
Use OAuth 2.0 in Spring Boot Applications
Configure OAuth 2.0 Resource Server
Keycloak Identity and Access Management Solution
Resource Servers behind API Gateway
Register Resource Servers with Eureka Service Registry
Application
Patterns
Decomposition
·
Decompose by business capability
·
Decompose by subdomain
Data Patterns
·
Database per service
·
Shared database
·
Saga
·
API Composition
·
CORS
·
Event Sourcing
·
Transaction Log tailing
·
Database Triggers
·
Application events
UI
·
Server-side page fragment composition
·
Client-side UI Composition
Testing
·
Service Component test
·
Service Integration contract test
Cross-cutting concerns
·
Microservice chassis
·
Externalized configuration
Security
·
Access Token
Communication Style
·
Remote procedure invocation
·
Messaging
·
Domain-specific protocol
Discovery
·
Client-side discovery
·
Self-registration
Reliability
·
Circuit breaker
Observability
·
Log Aggregation
·
Distributed Tracing
·
Exception Tracking
·
Health Check API
Deployment
·
Multiple service instance per Host
·
Service instance per host
·
Service instance for VM
·
Service instance for container
·
Serverless Deployment
·
Service deployment platform
External API
·
API Gateway
·
Back end for Front end
Microservice Architecture Pattern
Relationships
·
Predecessor
Precedes , but dictates the need for current pattern.
·
Successor
Solves problem generated by current pattern.
·
Alternative
Another pattern you can use instead of this one to solve the
problem .
·
Choice of Patterns
Pattern Chaining
·
More Decisions
Decompose by business capability
Decompose by subdomains
Choosing microservice architecture
Consistent
data (Database per service pattern)
Designing
for Failure
Potential risks associated with microservices
·
Network calls latency
·
Increased complexity
·
External services
Graceful service degradation
·
Contain failure
·
Failover logic
Change Management
·
Use automatic rollouts to lessen impact of
changes
E.g. Apply changes gradually
Use Multiple production environments
·
Deploy to one to test , then to all
·
Revert bad code , if needed
Load Balancing
·
Gather health information to avoid unhealthy
instances
·
Use external system to monitor health and
restart broken instances.
Failover caching
Retry logic
Want services to fail separately
o Use
bulkhead pattern to separate services
o Separate
resources to protect them
o Use
circuit breaker pattern
o Similar
to real circuit breaker
o Opens
when problem arises
o Stops
request to broken service
o Closes
after specific time for service to recover
Fail Quickly instead of waiting for Timeouts
Fundamental for Success
·
Potentials
·
Decisions
·
Fundamentals
·
Scoping Functionality
·
Prioritizing
·
Logical functionality
·
Organizational structure
·
Set limits
API Presentation
Exposed APIs
Managing Traffic
·
Monitor
·
Responsive API
·
Graceful exit
·
Volatility
Offloading Data
·
Always on
·
Shared redundancy
·
Data caching
Monitoring
·
Limited tools
·
Flexibility
·
Change is constant
·
Storage and metrics
·
Monitor in real-time
Monolithic vs. Microservices
The monolithic
architecture is the traditional way of building and
deploying applications. This structure is based around the concept of a single,
indivisible unit, including the server side, client side, and database. All
facets are unified and managed as a single unit and codebase. This means that
any updates must be made to the same codebase, so the whole stack must be
altered. As monolithic applications scale, they can become quite complex, so
the overall development is generally longer.
A microservices
architecture, on the other hand, breaks down that unit into
independent ones that function as separate services. This means that every
service has its own logic and codebase. They communicate with each other
through APIs (Application Programming Interfaces).
Choosing
a monolithic architecture
·
If your company is a small team. This
way you don’t have to deal with the complexity of deploying a microservice
architecture.
·
If you want a quicker launch. Monolithic
architecture requires less time to launch. This system will require more time
later on to update your system, but the initial launch is quicker.
Choosing
a microservices architecture
- If you want to develop a more scalable
application. Scaling a microservices
architecture is far easier. New capabilities and modules can be added with
much ease and speed.
- If your company is larger or plans to
grow. Using microservices is
great for a company that plans to grow, as a microservices architecture is
far more scalable and easier to customize over time.
Benefits and
drawbacks of microservices
Benefits
: Improves Scalability and Productivity
Large
teams often have to work together on complex projects. With microservices,
projects can be divided into smaller, independent units. This means that teams
can act independently regarding domain logic, which minimizes the coordination
and effort. On top of that, the teams responsible for each microservice can
make their own technology decisions depending on their needs.
For
example, the internal structure of each unit or container does not matter as
long as the interface functions correctly. Therefore, any programming language
can be used to write a microservice, so the responsible team can select the
best language for their teammates.
Integrates
well with legacy systems
Monolithic
systems are hard to maintain. Many legacy systems are poorly structured, poorly
tested, or depend upon outdated technologies. Luckily, microservices can work
alongside legacy systems to improve the code and replace old parts of the
system. Integration is easy and can solve many of the problems that make
monolithic systems something of the past.
Sustainable
development
Microservice
architectures create systems that remain maintainable in the long run since the
various parts are replaceable. This means that a microservice can easily be
rewritten without compromising the whole system. As long as the dependencies
between microservices are managed appropriately, changes can easily be made to
optimize team needs and performance.
Cross-functionality
Microservices
are best for distributed teams. If you have teams around the world or various
divisions, microservices grant the necessary freedoms and flexibility to work
autonomously. Technical decisions can be made quickly that integrate with other
services in a flash. Cross-functionality has never been easier.
Drawbacks: Deployment requires
more effort
The
operation of a microservice system often requires more effort, since there are
more deployable units that must each be deployed and monitored. Changes to
interfaces must be implemented so that an independent deployment of individual
microservices is still possible.
Testing must be independent
Since
all microservices must be tested together, one microservice can block the test
stage and prevent the deployment of the other microservices. There are more
interfaces to test, and testing has to be independent for both sides of the
interface.
Difficult to change multiple microservices
Changes
that affect multiple microservices can be more difficult to implement. In a
microservice system, changes require several coordinated deployments.
How are Microservices Flexible with
Spring Cloud?
Spring Cloud can help
developers with service configurations, service discovery, circuit-breaking,
load-balancing, distributed tracing & logging, and monitoring. It can even
sometimes act as an API gateway. Further terminologies that we use in the
development of Microservices including the java microservices tools.
What is Service Registration & Discovery?
When you have multiple services running together
within an application, they need to detect each other to communicate.
This the first and the most important feature of Microservices. In order to
make it possible, there should exist one medium where all microservices
register themselves. Subsequently, when any service wants to communicate, it
can connect to that medium and discovers other service to communicate. This
medium is nothing but ‘Service Registry & Discovery’ which is itself a
microservice. Moreover, this is similar to Java’s RMI mechanism, where you work
with a central registry so that RMI processes could find each other.
Microservices has the same obligation.
Netflix Eureka
Every Microservice will register into the Eureka
server with a service Id and Eureka server will have information(port,
IP addresses etc.) of all the microservices running as client applications. A
service (Spring Boot Application in our case) annotated with @EnableEurekaServer
will work as Eureka server.
<dependency>
<!-- Eureka for service registration -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
What
is Microservices Intra-communication?
A published
microservice communicates with the other microservice with the help of Eureka
Server itself. We use one Client to get details of a microservice from
Eureka Server. A service(Spring Boot Application in our case) annotated with @EnableEurekaClient
will work as a Eureka Client application.
1)DiscoveryClient (Legacy client) : This is a
basic client. It supports fetching Service Instances from Eureka server based
on Service Id as List type. Developer has to choose one instance with less load factor manually (no auto-balance concept supported)
from the list of Service Instances.
2)LoadBalancerClient (new client) : It will
fetch only one Service Instance from Eureka based on Service Id that has less
load factor. LoadBalancerClient is an interface. Its implementation is provided
by ‘Spring Cloud Netflix-Ribbon‘ i.e. RibbonLoadBalancerClient(C)
3)FeignClient/Open Feign (Abstract client) :
We also call it as Abstract Client or Declarative Rest Client. FeignClient is
an interface, at runtime one class gets generated using Dynamic Proxy Pattern.
This concept offers two annotations : @EnableFeignClients at starter class and
define interface for one Consumer with annotation
@FeignClient(name=”ServiceId”).
DiscoveryClient and LoadBalancerClient communicate
with Eureka to get Service Instance details, but they don’t support HTTP calls.
But, Feign Client acts as a combination client. In fact, it gets Service
Instance from Eureka Server, and supports making the HTTP call.
How to enable Load Balancer?
The previous versions of Spring Boot were using the
‘Ribbon’ to enable the load-balancing feature. However, we can get the
load balancing feature enabled if we are using ‘Feign Client’ & ‘Eureka’.
Below is the dependency to include ‘Feign Client’.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
What is API Gateway?
API Gateway is the single entry & exit point of all the
microservices in the application. Since every microservice has its own IP &
port, and we can’t provide multiple IP & port details to the client / end
user, there must be a single entry and exit point. It is also a type of
microservice, that calls all other microservices using Eureka and it should
also be registered with the Eureka Server like other microservices. It
generates a class(proxy) based on the service Id provided with the path(URL)
using a load balancer client. Then it selects one Service Instance from Eureka
and makes the HTTP call. This is obviously required because Eureka Server
itself can’t communicate with any microservice.
Eureka never supports making HTTP call to any
microservice. API Gateway helps in implementing Security, Applying
filters, SSO(Single Sing On), dynamic routing etc.
Zuul Proxy Server
In order to implement API Gateway, we can use Zuul
Proxy Server that handles all the requests and does the dynamic routing
of microservices. Dynamic routing is nothing but choosing one microservice
instance and make HTTP call based on the load. We also sometimes call it as
Zuul Server or Edge Server. We add the @EnableZuulProxy annotation on
our main application class to make our Spring Boot application act as a Zuul
Proxy server.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>.
Spring Cloud Gateway
Spring Cloud Gateway is a simple, yet an effective
way to route to APIs. It also offers implementation of various cross cutting
concerns such as Security,
Logging, Monitoring/metrics etc. It is built on top
of Spring Webflux (A reactive programming approach), We need to add
the dependency as given below in order to get features of Spring Cloud Gateway.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Some important features of the Spring Cloud Gateway
are:
1) Match routes on any request attribute
2) Define Predicates & Filters
3) Integrates with Spring Cloud Discovery Client
(Load Balancing)
4) Path Rewriting
What is Circuit Breaker?
If the actual method of a microservice is
continuously throwing exception, then stop executing actual method and redirect
each request to a fallback method, such concept is called Circuit Breaker. In
this situation, we configure a dummy method that will execute and give a
response back to the client such as ‘Service Not Working’, ‘Unable to Process
request at this time’, ‘try after some time’…etc. We call such a dummy method
as Fallback method. There are two types of circuit : open circuit & closed circuit.
In Open Circuit, client request directly moves to Fallback method. But In
closed Circuit, client request moves to the actual service method only.
Spring Cloud Hystrix
In order to implement Circuit Breaker mechanism, we
use Spring cloud Hystrix. We add the @EnableHystrix annotation on our
main application class to make our Spring Boot application act as a Circuit
Breaker. In addition, @HystrixCommand(fallbackMethod = “DUMMY METHOD NAME”)
at RestController method level. Additionally, you can visit our detailed
article on ‘How To
Implement Hystrix Circuit Breaker In Microservices Application?‘.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
Note: Currently, support
of Hystrix is not available as it has kept into the maintenance phase. The
other most popular tool is Resilience4j that we can use to take benefits of
Circuit Breaker for Fault Tolerance mechanism.
What is Fault Tolerance in Microservices?
In order to implement complete Fault Tolerance, even
including circuit breaker, we use Resilience4j API. It has multiple separate
modules such as Rate Limiter, Time Limiter, Bulkhead, Circuit Breaker, Retry
etc. We have separate annotations for each functionality as @RateLimiter,
@TimeLimiter, @Bulkhead, @CircuitBreaker, @Retry
respectively. However, we can also implement these functionalities
programmatically by using Decorator pattern. Moreover, we require below
dependencies to implement Resilience4j. Additionally, you can visit our
detailed article on ‘How To
Implement Fault Tolerance In Microservices Using Resilience4j?‘.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
What is Spring Cloud Config Server?
The common properties file will have association
with every microservice using Config Server. Common ‘key=value’ properties are
like, DB Connection, Email, Security etc. However, we can handle
it in two ways : External Config Server and Native Config Server. We can
implement External Config Server by using GitHub, GitLab, Bitbucket etc. We can
implement Native Config Server just by using local drives of our system which
is appropriate only for development environment.
Moreover, we add the @EnableConfigServer annotation on our main
application class to make our Spring Boot application act as a Config Server.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
What is Distributed Tracing & Logging?
In real time one application can have multiple
microservices. Further, one request can involve multiple microservices till the
completion of the request. Then the manual tracing of all microservices
involved in a request becomes a lengthy task. Here, tracing is the process of
finding an execution path or flow of multiple microservices involved in serving
a request. Also, Logging is not going to be a simple process as each
microservice will have its own log file. Therefore, implementation of a Distributed
Tracing & Logging mechanism becomes mandatory.
Sleuth
In order to implement Distributed Tracing &
Logging, Spring Cloud API offers two cloud components : Sleuth &
Zipkin. Sleuth provides unique IDs for request flows. The developer uses
this ID to find the execution flow of a request. There are two types of IDs
: Trace ID and Span ID. Trace ID is a unique Id is
for a complete flow (from Request till Response). Using this ID, developer can
find out logs of all microservices involved in the flow. Span Id is a unique ID
for one microservice flow. Using this ID, developer can find out log messages
for a particular microservice.
Zipkin
Zipkin works in a client
server model. In every microservice, we should also add this dependency
along with Sleuth. It contains Sampler (Collect data from microservice
using Sleuth and provide to Zipkin Server). There must be only one centralized Zipkin
Server that collects all data from Zipkin Client and displays it as a UI.
Now, Developer should make a request and goto Zipkin Server to find Trace ID,
Span ID and flow as well. Then the developer should open Log files to see Log
lines related to current Trace Id.
Additionally, you can visit our detailed article
on ‘How To
Implement Distributed Logging & Tracing Using Sleuth & Zipkin?‘.
ELK Stack
ELK Stack (Elasticsearch, Logstash, Kibana) is one
of the most popular tools to monitor our application via log analysis. Further,
to get a deeper view on it, kindly visit our article on ‘How To Monitor
Spring Boot Microservices Using ELK Stack?‘.
What
is Spring Boot Admin Dashboard?
Spring
Boot Admin is a web application that manages and monitors multiple Spring boot applications(microservices
in our case) and shows the results in the form of a single dashboard.
Generally, microservices developers use it for monitoring of webservices. If we
add Spring Actuator to the Spring Boot applications, we can get multiple endpoints
to monitor and deal with Spring Boot applications. Each Spring Boot application
acts as a client and registers to the Spring Boot Admin Server. Spring Boot
Actuator endpoints provides the magic behind the scene. We apply Actuator to
Spring Boot Admin Client Applications and expect the results in Spring Boot
Admin Server in the form of a dashboard.
Moreover, we add the @EnableAdminServer
annotation on our main application class to make our Spring Boot application
act as a Spring Boot Admin Server.
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
Spring Boot Actuator
Spring Boot Actuator provides endpoints for managing
and monitoring of your Spring Boot application. All actuator endpoints secure
by default. Endpoints are nothing but details to access a web service such as
path(/emp/data), http method(GET), input(String), output(JSON) etc. In order to
enable Spring Boot Actuator in your application, you need to add the Spring
Boot Starter Actuator dependency in your pom.xml file as given below.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Some of the popular & important actuator
endpoints are as given below. You can enter them in your web browser and
monitor the behavior of your application.
env : in order to know
the environment variables used in the application.
beans : in order to view
the Spring beans and its types, scopes and dependency used in the application.
health : in order to view
the application health. Moreover, this endpoint says ‘IS OUR APPLICATION
STARTED PROPERLY OR NOT?’. Additionally, we can get the data like Memory for
Disk Space, PING STATUS etc.
info : in order to get
information of current microservice to other Clients/Users/Dev etc.
trace : in order to view
the list of traces of your Rest endpoints.
metrics : in order to view
the application metrics such as memory used, free memory, classes, threads,
system uptime etc.
WEBSERVICE- W3C DEFINITION
Software system designed to support interoperable
machine-to-machine interaction over a network.
3 KEYS
·
Designed for machine-to-machine (or
Application-to-application ) interaction
·
Should be interoperable – Not platform dependent
·
Should allow communication over a network
Webservice having Request Response formats are like below
·
XML (Request & Response)
·
JSON
Example :
[
{
“id” : 1,
“name” :”Even”,
“birthdate” : “2017-07-10T07:52:48.270+0000”
};
{
“id” : 2,
“name” :”Ade”,
“birthdate” :
“2017-07-10T07:52:48.270+0000”
}; ]
KEY TERMINOLOGY
·
Request & Response
·
Message Exchange Format : XML and JSON
·
Service Provider and Server
·
Service Consumer or Client
·
Service Definition
·
Transport :
HTTP and MQ
Service Definition
WEBSERVICE GROPUS
·
SOAP-Based
·
REST-Based
SOAP and REST are not really comparable
SOAP Defines below Format for Request and Response in xml
Format
·
SOAP xml Request
·
SOAP xml Response
Transport
·
SOAP Over MQ
·
SOAP Over HTTP
Service Definition
·
WSDL (Webservice Define Language)
-
Endpoint
-
All operation
-
Request Structure
-
Response Structure
SOAP HEADER , ENVELOP...
Introduction to RESTFUL Webservices (Representational
State Transfer)
In Rest webservices
the format of Request and Response would be HTTP
HTTP REQUEST METHODS
-
GET
-
PUT
-
POST
-
DELETE
-
TRACE
Key ABSTRACTION - RESOURCE
A Resource has an URI
(Uniform Resource Identifier)
§ /user/Ranga/todos/1
§ /user/Ranga/todos
§ /user/Ranga
A resource can have different
representations
§ XML
§ HTML
§ JSON
Example
-
Create a User :
POST/users
-
Delete a User :
DELETE/users/1
-
Get All Users :
GET/users
-
Get One User :
GET/user/1
In REST
Data Exchange Format
-
No restriction .
JSON is popular
Transport
-
Only HTTP
Service Definition
-
No Standard .
WADL/Swagger/…
REST Vs SOAP
-
Restriction s
Architectual Approach
-
Data Exchange
format
-
Service
Definition
-
Ease of
Implementation
RestFul WebServices with Spring Boot
To Start Spring boot application using via Spring Initalizr
in28minutes-initiatives/quick-start.md
at master · in28minutes/in28minutes-initiatives · GitHub
Rest
is a Style of software architecture for distributed hypermedia systems.
#
Restful webservices
Social
Media Application
User
->Posts(1-M one to Many relationships)
-
Create a User :
POST/users
-
Delete a User :
DELETE/users/1 Ã DELETE/users/{id}
-
Retrive All Users
: GET/users
-
Get One User :
GET/user/1-> GET/user/{id}
1.
Retrive All posts
for a User : GET/users/{id}/posts
2.
Create a posts
for a User : POST/users/{id}/posts
3.
Retrive details
of a Post : GET/users/{id}/posts/{post_id}
What is DispatcherServelet?
Who is configuring dispatcher servlet?
What does dsipatcher servelet do ?
How does helloworldbean object get converted to JSON?
Who is configuring the erro mapping ?
Mapping servlet : ‘dispatcherServlet’ to [/]
Mapped to “{[/hello-world],methods=[GET]}” on to
public java.lang.String
com.in28minutes.rest.webservices.controller.HelloWorldController.helloworldBean()
Mapped “{[/error]}” on to
public org.springframework.http.ResponeEntity
<java.util.Map<java.lang.String ,
-- mappped o “{[/error], produces =[text/html]}” on to
public org.springframework.web.servlet.ModelAndView
Implementing
Generic Exception handling for all Resources
HTTP Response Codes
201
– CREATED (resource : for HTTP Response Code)
200
– OK ( SUCCESS)
404
– Resource Not Found /Not Found
500
– Internal Server Error
ResponseEntityExceptionHandler
Exercise
1.
Retrive All posts
for a User : GET/users/{id}/posts
2.
Create a posts
for a User : POST/users/{id}/posts
3.
Retrive details
of a Post : GET/users/{id}/posts/{post_id}
HATEOS
Hyper
Media As The Engine of Application State
Sample
<EntityModel>
<id>1</id>
<name>Adam</name>
<birthDate>2022-02-28T06:27:11.016+00:00</birthDate>
<links>
<rel>all-users</rel>
<href>http://localhost:8080/users</href>
</links>
</EntityModel>
·
I18n (Internationalization) (En, Fr,de…. Remain
languages)
·
Content Negotiation
Content
Negotiation : Dependency needs to be
added in pom.xml
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<List>
<item>
<id>1</id>
<name>Adam</name>
<birthDate>2022-02-28T06:36:53.084+00:00</birthDate>
</item>
<item>
<id>2</id>
<name>EVe</name>
<birthDate>2022-02-28T06:36:53.084+00:00</birthDate>
</item>
<item>
<id>3</id>
<name>Jack</name>
<birthDate>2022-02-28T06:36:53.084+00:00</birthDate>
</item>
<item>
<id>4</id>
<name>KAdam</name>
<birthDate>2022-02-28T06:36:53.084+00:00</birthDate>
</item>
<item>
<id>5</id>
<name>MAdam</name>
<birthDate>2022-02-28T06:36:53.084+00:00</birthDate>
</item>
</List>
Swagger
: to View All API Details
Actuator : It will verify all endpoint URL’s , Health
Metrics of Application etc..
Visualizing API with HALO Explorer
HAL and the HAL Browser
JSON
Hypertext Application Language, or HAL, is a simple
format that gives a consistent and easy way to
hyperlink between resources in our API. Including HAL within our REST API makes it much more explorable to
users as well as being essentially self-documenting.
It works by returning data in JSON format which outlines relevant
information about the API.
Versioning
Media type versioning
(a.k.a “content-negotiation” or “accept header”)
-
GitHub
-
((Custom)
header versioning
-
Microsoft
-
URI
Versioning
-
Twitter
-
Request
Parameter Versioning
-
Amazon
-
Factors
-
URI Pollution
-
Misuse of HTTP
headers
-
Caching
Can we execute on the
request on the browser ?
API Documentation , NO
perfect solution
DEBUGGING GUIDE (If you have problems)
JPA Hibernate Debugging Guide: https://github.com/in28minutes/in28minutes-initiatives/blob/master/The-in28Minutes-TroubleshootingGuide-And-FAQ/jpa-and-hibernate.md
COURSE UPDATE: Two Important
Things to Remember
UPDATE 1: SWAGGER
With the recent update (2.5.0) to use springdoc-openapi-ui
,
·
You do not need ApiModel and ApiModelProperty annotations
(needed with older Swagger frameworks)
·
Do NOT worry if you see these annotations in User bean (Ignore
them)
1.
//IGNORE THESE ANNOTATIONS
2.
@ApiModel(description="All details about the user.")
3.
@ApiModelProperty(notes="Name should have atleast 2 characters")
4.
@ApiModelProperty(notes="Birth date should be in the past")
UPDATE 2: HATEOAS
HATEOAS code with earlier versions looks something like this:
Resource and ControllerLinkBuilder instead of EntityModel and WebMvcLinkBuilder.
1. //Do
not worry about Resource and ControllerLinkBuilder
2. Resource<User> resource = new Resource<User>(user);
3. ControllerLinkBuilder linkTo =
4. linkTo(methodOn(this.getClass()).retrieveAllUsers());
Level 0 : EXPOSE SOAP WEBSERVICES
IN REST STYLE
Level -1 :
EXPOSE RESOURCES WITH PROPER URI
Note: IMPROPER
Use of HTTP Methods
Level 2 = Level
1+Http Methods
Level 3= Level
2+ HATEOS
data + next
possible actions
RICHARDSON
MATURITY MODEL
BEST
PRACTICES:-
CONSUMER FIRST
REQUEST METHODS
·
GET
·
POST
·
PUT
·
DELETE
No Secure info
in URI
USE PLURALS
·
Prefer/users
to/user
·
Prefer/users/1
to/user/1
Use Nouns for
Resources For Exceptions
Define A Constant
CONSISTENT Approach
·
/search
·
PUT/gists/{id}/star
·
DELETE/gists/{id}/star
Introduction to Microservices with Spring boot and Spring Cloud
·
Spring cloud server config and Bus
·
Load balancing with Ribbon and Feign
·
Implement naming server with Eureka
·
Distributed tracing with Zipkin
·
Fault Tolerance with Hystrix
GitHub
- in28minutes/spring-microservices: Spring Microservices using Spring Cloud
https://github.com/in28minutes/spring-microservices.git
spring-microservices/03.microservices
at master · in28minutes/spring-microservices · GitHub
Introduction to Micro Services
Small autonomous services that work together – Sam
Newman
“In short Microservice is an architectural style is an
approach developing a suite of small services , each running on its own process
and communicating with lightweight mechanism’s often HTTP resource API ….”
There is a bare minimum centralized management of these
services , which may be written in different programming languages and use
different data storage technologies – James Lewis and Martin Flower
These services are build around business capabilities and
independently deployable by fully automated deployment machinery ..
Microservices
·
Restful webservice
·
Small well-chosen deployable units
·
Cloud Enabled
Microservice1->microservice 2->microservice3Ã microservice 4 ….
Microservice N
Microservice 1 having ->
A1 and A2
|
Microservice 2 having B1 B2 B3 B4
|
Microservice 3 with C1
Challenges with Microservices
PACK OF CARDS
Challenges
·
Bounded Context
·
Configuration management
·
Dynamic Scaleup and Scale Down
·
VISIBILITY
·
PACK OF CARDS
·
FAULT TOLERENCE
SPRING CLOUD
Spring
Cloud provides tools for developers to quickly build some of the common
patterns in distributed systems (e.g. configuration management, service
discovery, circuit breakers, intelligent routing, micro-proxy, control bus,
one-time tokens, global locks, leadership election, distributed sessions,
cluster state). Coordination of distributed systems leads to boiler plate
patterns, and using Spring Cloud developers can quickly stand up services and
applications that implement those patterns. They will work well in any
distributed environment, including the developer’s own laptop, bare metal data centers,
and managed platforms such as Cloud Foundry.
Features
Spring Cloud focuses on providing good out of box experience for
typical use cases and extensibility mechanism to cover others.
·
Distributed/versioned configuration
·
Service registration and discovery
·
Routing
·
Service-to-service calls
·
Load balancing
·
Circuit Breakers
·
Global locks
·
Leadership election and cluster state
·
Distributed messaging
Spring
Cloud
Netflix
Spring Cloud Netflix provides Netflix OSS integrations for
Spring Boot apps through autoconfiguration and binding to the Spring
Environment and other Spring programming model idioms. With a few simple
annotations you can quickly enable and configure the common patterns inside
your application and build large distributed systems with battle-tested Netflix
components. The patterns provided include Service Discovery (Eureka), Circuit
Breaker (Hystrix), Intelligent Routing (Zuul) and Client Side Load Balancing
(Ribbon)
Challenges
: Configuration Management
·
Spring Cloud Config Server
·
Dynamic scaleup and down
·
Naming server (EUREKA)
·
Ribbon (Client-Side Load Balancing)
·
Feign (Easier REST Client’s) to write simple rest
clients
·
Ribbon Load Balancing
·
Service Registration
·
Service Discovery
·
VISIBILITY and MONITORING
·
Zipkin Distributed Tracing
·
Netflix API Gateway
·
FAULT TOLERANCE
·
Hystrix
Advantages of Microservice Architecture
·
New technology & Process Adaption using
simple messages
·
Dynamic Scaling (Amazon with Load Balances based
on Those Holidays will configure the hardware and scale up and scale down based
on Load balancing)
·
Faster Release Cycles.
Microservice Components -
standardizing Ports
Application |
Port |
Limits
Service |
8080,
8081, ... |
Spring
Cloud Config Server |
8888 |
Currency
Exchange Service |
8000,
8001, 8002, .. |
Currency
Conversion Service |
8100,
8101, 8102, ... |
Netflix
Eureka Naming Server |
8761 |
Netflix
Zuul API Gateway Server |
8765 |
Zipkin
Distributed Tracing Server |
9411 |
URLs
Application |
URL |
Limits Service |
http://localhost:8080/limits http://localhost:8080/actuator/refresh (POST) |
Spring Cloud Config Server |
http://localhost:8888/limits-service/default http://localhost:8888/limits-service/dev |
Currency Converter Service - Direct Call |
http://localhost:8100/currency-converter/from/USD/to/INR/quantity/10 |
Currency Converter Service - Feign |
http://localhost:8100/currency-converter-feign/from/EUR/to/INR/quantity/10000 |
Currency Exchange Service |
http://localhost:8000/currency-exchange/from/EUR/to/INR http://localhost:8001/currency-exchange/from/USD/to/INR |
Eureka |
|
Zuul - Currency Exchange & Exchange
Services |
http://localhost:8765/currency-exchange-service/currency-exchange/from/EUR/to/INR http://localhost:8765/currency-conversion-service/currency-converter-feign/from/USD/to/INR/quantity/10 |
Zipkin |
|
Spring Cloud Bus Refresh |
Microservices V1 and V2
V2 is latest release of
·
Spring Boot
·
Spring cloud
·
Docker and Kubernetes
V1 Older versions
Spring Boot v2.3 and LOWER
Continue on next lecture ☹
Microservice Environments
CCPROD CEPROD LSPROD
CCSTAGE CESTAGE LSSTAGE
CCQA CEQA LSQA
CCDEV CEDEV LSDEV
CurrencyCalculationservice
à CurrencyExchangeservice à LimitService
Currency Conversion Service
DEV
QA STAGE PROD
DEV1
QA1 QA2 STAGE1 PROD1
Currency Exchange Service (All Environments)
DEV
QA STAGE PROD
DEV1
QA1 QA2 STAGE1 PROD1
PROD2 PROD3 PROD4
Spring Cloud Config Server
CurrencyCalculationService CurrencyExchangeService LimitsService
Spring
Cloud Config Server
Git
Limits service with >=2.4.0 of SPRING BOOT
If you are using 2.4.0, you need to add this dependency to
the pom.xml:
HINT: Make
sure that you RESTART the server after saving your pom.xml
1.
<dependency>
2.
<groupId>org.springframework.cloud</groupId>
3.
<artifactId>spring-cloud-starter-bootstrap</artifactId>
4.
</dependency>
Debugging problems with
Spring Cloud Config Server
If you are using 2.4.0, you need to add this dependency
to the pom.xml:
1. <dependency>
2. <groupId>org.springframework.cloud</groupId>
3. <artifactId>spring-cloud-starter-bootstrap</artifactId>
4. </dependency>
Ribbon DOES NOT work with Spring Boot 2.4
GREAT NEWS: We are re-recording this
course with the new version of Spring Cloud. I expect the update to be
available before the end of January 2021. I expect the update to include Docker
and Kubernetes on top of what we already have!
In the
meanwhile, we recommend using 2.3.1.RELEASE with Hoxton.SR5.
1. <parent>
2. <groupId>org.springframework.boot</groupId>
3. <artifactId>spring-boot-starter-parent</artifactId>
4. <version>2.3.1.RELEASE</version>
5. <relativePath/> <!-- lookup parent from repository -->
6. </parent>
7.
8. <properties>
9. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
10. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
11. <java.version>1.8</java.version>
12. <spring-cloud.version>Hoxton.SR5</spring-cloud.version>
13. <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
14. </properties>
Debugging problems with Feign and Ribbon
Debugging microservices problems can be difficult as there are
multiple components involved.
Step by Step instructions are
provided in the troubleshooting guide to help you
troubleshoot frequently occurring problems.
Using Chrome Browser is recommended.
Exclude dependency on
jackson-dataformat-xml
OPEN BUG with spring-cloud-starter-netflix-eureka-client
It uses jackson-dataformat-xml.
Hence, you would see XML responses instead of JSON responses
in the browser.
If you want to see JSON responses, you can add an exclusion
for jackson-dataformat-xml dependency.
You need to make this change in 2 POM.XML files -
Currency Exchange and Currency Conversion
1.
<dependency>
2.
<groupId>org.springframework.cloud</groupId>
3.
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
4.
<exclusions>
5.
<exclusion>
6.
<groupId>com.fasterxml.jackson.dataformat</groupId>
7.
<artifactId>jackson-dataformat-xml</artifactId>
8.
</exclusion>
9.
</exclusions>
10. </dependency>
Debugging Problems with Naming Server ( Eureka ) and Ribbon
Debugging microservices problems can be difficult as there are
multiple components involved.
Step by Step instructions are provided in
the troubleshooting guide to
help you troubleshoot frequently occurring problems.
Using Chrome Browser is recommended.
Ribbon Load Balancing
Netflix Ribbon is
an Inter Process Communication (IPC) cloud library. Ribbon primarily provides
client-side load balancing algorithms.
Apart from the client-side load balancing algorithms, Ribbon
provides also other features:
- Service
Discovery Integration –
Ribbon load balancers provide service discovery in dynamic environments
like a cloud. Integration with Eureka and Netflix service discovery
component is included in the ribbon library.
- Fault
Tolerance – the
Ribbon API can dynamically determine whether the servers are up and
running in a live environment and can detect those servers that are down
- Configurable load-balancing rules – Ribbon supports RoundRobinRule, AvailabilityFilteringRule, WeightedResponseTimeRule out
of the box and also supports defining custom rules. Ribbon API works based
on the concept called “Named Client”. While configuring Ribbon in our
application configuration file we provide a name for the list of servers
included for the load balancing.
API GATEWAYS
·
Authentication & authorization , security
·
Rate Limits
·
Fault Toleration .
·
Service Aggregation
Router and Filter: Zuul [API GATEWAY]
Routing is an integral part of a microservice architecture. For
example, /
may be mapped to your web
application, /api/users
is mapped to the
user service and /api/shop
is mapped to the
shop service. Zuul is a JVM-based router and server-side
load balancer from Netflix.
Netflix uses Zuul for the following:
·
Authentication
·
Insights
·
Stress Testing
·
Canary Testing
·
Dynamic Routing
·
Service Migration
·
Load Shedding
·
Security
·
Static Response handling
·
Active/Active traffic management
8. Router
and Filter: Zuul (spring.io)
Getting
Started | Routing and Filtering (spring.io)
Direct URL to execute currency-exchange service
http://localhost:8000/currency-exchange/from/EUR/to/INR
http://localhost:8765/currency-exchange-service/currency-exchange/from/EUR/to/INR
Call through API Gate way through Zuul API
Server using Proxy
localhost:8100/currency-converter-feign/from/USD/to/INR/quantity/10
Debugging Problems with Zuul API Gateway
Debugging microservices problems can be difficult as there are
multiple components involved.
Step by Step
instructions are provided in the troubleshooting
guide to help you troubleshoot frequently occurring problems.
Using Chrome Browser is recommended.
Introduction to Distributed Tracing
How do you do distributed tracing in Microservices?
Distributed tracing, sometimes called
distributed request tracing, is a method to monitor applications built on a
microservices architecture. IT and DevOps teams use distributed tracing to
follow the course of a request or transaction as it travels
through the application that is being monitored.
Distributed Tracing with
Spring Cloud Sleuth and Spring Cloud Zipkin
Features
Sleuth configures everything you
need to get started. This includes where trace data (spans) are reported to,
how many traces to keep (sampling), if remote fields (baggage) are sent, and
which libraries are traced.
Specifically, Spring
Cloud Sleuth…
Adds trace and span ids to the
Slf4J MDC, so you can extract all the logs from a given trace or span in a log
aggregator.
Instruments common ingress and
egress points from Spring applications (servlet filter, rest template,
scheduled actions, message channels, feign client).
If spring-cloud-sleuth-zipkin is
available, then the app will generate and report Zipkin-compatible traces via
HTTP. By default, it sends them to a Zipkin collector service on localhost
(port 9411). Configure the location of the service using spring.zipkin.baseUrl.
Spring Boot Config
: Add Sleuth to your classpath:
Maven
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${release.train.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
</dependencies>
Running Zipkin on
Windows
In the
next step, we set up our Zipkin Server by downloading a jar.
Here is
the URL you can use to download Zipkin jar
https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec
If you get a 404 while downloading the jar, use the curl command to
download :
1.
curl -sSL https://zipkin.io/quickstart.sh
| bash -s
2.
java -jar zipkin.jar
For more information, please go through the below link:
https://zipkin.io/pages/quickstart
ONLY FOR WINDOWS USERS
If you are on Windows,
this is important for you:
After you watch the next video, You
can use the below commands to run Zipkin Server.
1.
set RABBIT_URI=amqp://localhost
2.
java -jar zipkin-server-2.7.0-exec.jar
Use
spring-cloud-starter-zipkin and spring-rabbit
The dependencies are ever-changing
with Spring Cloud and Spring Boot.
If you are using Spring Boot Release >= 2.1.*, you would need
to use spring-cloud-starter-zipkin and spring-rabbit instead
of spring-cloud-sleuth-zipkin and spring-cloud-starter-bus-amqp.
You
would need to make this change in THREE pom.xmls - in
currency-conversion-service, currency-exchange-service, and zuul-api-gateway
projects
New Dependencies
1. <dependency>
2. <groupId>org.springframework.cloud</groupId>
3. <artifactId>spring-cloud-starter-zipkin</artifactId>
4. </dependency>
5. <dependency>
6. <groupId>org.springframework.amqp</groupId>
7. <artifactId>spring-rabbit</artifactId>
8. </dependency>
OLD Dependencies to
be Replaced
1. <dependency>
2. <groupId>org.springframework.cloud</groupId>
3. <artifactId>spring-cloud-sleuth-zipkin</artifactId>
4. </dependency>
5.
6. <dependency>
7. <groupId>org.springframework.cloud</groupId>
8. <artifactId>spring-cloud-starter-bus-amqp</artifactId>
9. </dependency>
Zipkin is a very efficient tool for distributed tracing in
the microservices ecosystem. Distributed tracing, in general, is the latency
measurement of each component in a distributed transaction where multiple
microservices are invoked to serve a single business use case.
Zipkin is a Java-based app used for distributed tracing and
identifying latency issues. Unique identifiers are automatically attached
to requests which are then passed downstream through the different waypoints,
or services.
What is the use of
zipkin in spring boot?
Zipkin is an application
that monitors and manages the Spring Cloud Sleuth logs of your Spring
Boot application. To build a Zipkin server, we need to add the Zipkin UI
and Zipkin Server dependencies in our build configuration file.
Debugging Problems with Zipkin
Debugging microservices problems can be difficult as there are
multiple components involved. Step by Step instructions are
provided in the troubleshooting guide to help you
troubleshoot frequently occurring problems.
Using Chrome Browser is recommended.
Implementing
Spring Cloud Bus
Add Dependency in POM.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Fault Tolerance with Hystrix
Microservices must be extremely
reliable because they depend on each other. The microservice architecture
contains a large number of small microservices. These microservices communicate
with each other in order to fulfill their requirements.
The instances of microservices may
go up and down frequently. As the number of interactions between microservices increases, the
chances of failure of the microservice also increases in the system.
Fault Tolerance
Consider a scenario
in which six microservices are communicating with each other. The microservice-5 becomes
down at some point, and all the other microservices are directly or indirectly
depend on it, so all other services also go down.
The solution to this
problem is to use a fallback in case of failure of a
microservice. This aspect of a microservice is called fault
tolerance.
Fault
tolerance can be achieved with the help of a circuit
breaker. It is a pattern that wraps requests to external
services and detects when they fail. If a failure is detected, the circuit
breaker opens. All the subsequent requests immediately return an error instead
of making requests to the unhealthy service. It monitors and detects the
service which is down and misbehaves with other services. It rejects calls
until it becomes healthy again.
The Circuit breaker
implemented via a finite state machine with three normal states CLOSED, OPEN and HALF_OPEN
and two special states DISABLED and FORCED_OPEN
Hystrix
Hystrix is a library
that controls the interaction between microservices to provide latency and
fault tolerance. Additionally, it makes sense to modify the UI to let the user
know that something might not have worked as expected or would take more time.
Implementing
Fault Tolerance with Hystrix
Open the pom.xml file of limits-service and
add the Hystrix dependency
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
- </dependency>
Fallback method
The fallback method is a method that invokes when a
fault occurs. Hystrix allows us to define a fallback method for each service
method. Here one question arises that if the method throws an exception, what
should be returned to the consumer?
So answer is that if retrieveConfiguraion() fails,
the method fallbackRetrieveConfiguration() is called.
The fallback method returns the hardcoded LimitConfiguration instance.
Open the browser and invoke the URL http://localhost:8080/fault-tolerance-example. It returns the values that we have returned in the fallbackRetrieveConfiguration() method.
Microservices with Spring Cloud V2
·
Microservices Evolve Quickly
Important Updates
·
Latest versions of springboot and Spring cloud
·
Spring Cloud Load Balancer instead of Ribbon
·
Spring Cloud Gateway instead of Zuul
·
Resilience 4J instead of Hystrix
Docker : Centralize Microservices
·
Run microservices using Docker and Docker
compose
Kubernetes: Orchestrate all your Microservices with
Kubernetes.
You have Skipped V1
-
Go to next Lecture
You have completed V1
Option 1: Start from Zero again , Go to Next Lecture !
Option 2: Jump
to “Step 21 Quick Start by implementing Microservices”
-
Same microservice as V1: Currency Exchange and Currency
Conversion
-
Very little changes on Eureka Naming Server
-
Step 21 helps you get these up and
started quickly !
Master
Microservices with Spring Boot and Spring Cloud | Udemy
CODE BACKUP FILES and STEP BY STEP CHANGES : For Reference
Help for Debugging Problems:
1.
Here's the code backup at the end of Step 07: https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/step07.md
2.
Step by Step changes are detailed here:https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/01-step-by-step-changes/microservices-v2-1.md#step-01
Two Recommended Activities:
Activity - 1 : Explore
other backups for this section (Steps 08,10,13,15,21,25,29, final) - https://github.com/in28minutes/spring-microservices-v2/tree/main/03.microservices
Activity - 2 : Get
Familiar with the structure of Step by Step changes file - https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/01-step-by-step-changes/microservices-v2-1.md#step-01
We will make use of these in the next
lecture!
URL
http://localhost:8000/currency-exchange/from/USD/to/INR
Response Structure
1. {
2. "id":10001,
3. "from":"USD",
4. "to":"INR",
5. "conversionMultiple":65.00,
6. "environment":"8000
instance-id"
Currency
Exchange service
http://localhost:8000/currency-exchange/from/EUR/to/INR
Currency
Conversion service
http://localhost:8100/currency-conversion/from/EUR/to/INR/quantity/10
http://localhost:8100/currency-conversion-feign/from/USD/to/INR/quantity/10
Eureka
Server
CODE BACKUP FILES and STEP BY STEP CHANGES : For Reference
Help for Debugging Problems:
·
Here's the code backup at the end of Step 13: https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/step13.md
·
Step by Step changes are detailed here: https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/01-step-by-step-changes/microservices-v2-1.md#step-13
Two Recommended Activities:
Activity - 1 : Explore
other backups for this section (Steps 08,10,13,15,21,25,29, final) - https://github.com/in28minutes/spring-microservices-v2/tree/main/03.microservices
Activity - 2 : Get Familiar
with the structure of Step by Step changes file - https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/01-step-by-step-changes/microservices-v2-1.md#step-13
URL and Response Structure for Currency Conversion Service
We will make use of
these in the next lecture!
URL
http://localhost:8100/currency-conversion/from/USD/to/INR/quantity/10
Response Structure
1.
{
2.
"id": 10001,
3.
"from": "USD",
4.
"to": "INR",
5.
"conversionMultiple": 65.00,
6.
"quantity": 10,
7.
"totalCalculatedAmount": 650.00,
8.
"environment": "8000 instance-id"
9.
}
Debugging Problems with Eureka -
V2
Debugging microservices problems can
be difficult as there are multiple components involved.
Step by Step instructions is provided in the troubleshooting
guide to help you troubleshoot frequently occurring problems.
Using the Chrome Browser is
recommended.
Sequence would be start with
Microservices for the below
Start Eureka server -> Naming
server ->Currency exchange service->currency converter service
Load Balancing with Eureka , feign & Spring Cloud
Load Balancer
Setting with Spring Cloud API Gateway
URLs for next Lecture
Some
of these URLs may be complex to write by hand:
Refer
back to here if you have problems in the next steps.
API GATEWAY URLS
Initial
-
http://localhost:8765/CURRENCY-EXCHANGE/currency-exchange/from/USD/to/INR
-
http://localhost:8765/CURRENCY-CONVERSION/currency-conversion/from/USD/to/INR/quantity/10
-
http://localhost:8765/CURRENCY-CONVERSION/currency-conversion-feign/from/USD/to/INR/quantity/10
Lower Case
- http://localhost:8765/currency-exchange/currency-exchange/from/USD/to/INR
-
http://localhost:8765/currency-conversion/currency-conversion/from/USD/to/INR/quantity/10
-
http://localhost:8765/currency-conversion/currency-conversion-feign/from/USD/to/INR/quantity/10\
Custom Routes
- http://localhost:8765/currency-exchange/from/USD/to/INR
- http://localhost:8765/currency-conversion/from/USD/to/INR/quantity/10
- http://localhost:8765/currency-conversion-feign/from/USD/to/INR/quantity/10
- http://localhost:8765/currency-conversion-new/from/USD/to/INR/quantity/10
COMPLETE DEBUGGING GUIDE
TOP Recommendation from Debugging Guide:
(6) Some student reported success when using
lower-case-service-id instead of
spring.cloud.gateway.discovery.locator.lowerCaseServiceId. See if it helps!
1.
spring.cloud.gateway.discovery.locator.enabled=true
2.
3.
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
Spring Cloud Gate way
-
Simple , yet effective way to
route to APIs
-
Provide cross cutting concerns
-
Security
-
Monitoring/metrics
-
Built on top of Spring web Flux
(Reactive approach)
Features
-
Match routes on request attribute
-
Define predicts and filters
-
Integrates with Spring Cloud
Discovery Client (Load Balancing)
-
Path Rewriting
Circuit Breaker
Micorservice1Ã Microservice2Ã Microservice3Ã Microservice4
What
if one of the service is down or slow ?
Impacts
entire chain !
Questions:
-
Can we return fallback response
if a service is down ?
-
Can we implement a circuit
breaker pattern to reduce load ?
-
Can we retry requests in case of
temporary failures?
-
Can we implement rate limiting?
Solution : Circuit Breaker Framework -Resilence4j
Resilience4j is a
lightweight, easy-to-use fault tolerance library inspired by
Netflix Hystrix, but designed for Java
8 and functional programming. Lightweight, because the library only uses Var, which does not have any other external library
dependencies. Netflix Hystrix, in contrast, has a compile dependency to
Archaius which has many more external library dependencies such as Guava and
Apache Commons Configuration.
Resilience4j provides higher-order functions (decorators)
to enhance any functional interface, lambda expression or method reference with
a Circuit Breaker, Rate Limiter, Retry or Bulkhead. You can stack more than one
decorator on any functional interface, lambda expression or method reference.
The advantage is that you have the choice to select the decorators you need and
nothing else.
With Resilience4j you don’t have to go all-in, you can
pick what you need.
Change in Configuration
Use maxAttempts instead
of maxRetryAttempts
1. resilience4j.retry.instances.sample-api.maxAttempts=5
#NEW
2. #resilience4j.retry.instances.sample-api.maxRetryAttempts=5
#OLD
LEARN
DOCKER : DEVELOPING Spring Boot Applications
After installing docker
docker –version
Use PowerShell in
Windows!
Recommendation 1
If
you are using Windows, make sure that you use PowerShell instead of Command
Prompt.
Recommendation 2
If you are using Window
10 and are using docker toolbox
=> Use 192.168.99.100 instead
of localhost.
Note: If 192.168.99.100 does
not work, you can find the IP by using the command docker-machine
ip
Reason
In Window 10 when using docker
toolbox, docker is configured to use the default machine with IP
192.168.99.100
Install Docker Engine | Docker
Documentation
Some of the Commands for
Docker :-
docker container ls -a
docker run -p 5000 :5000
in28min/todo-rest-api-h2:0.0.1-SNAPSHOT
docker images
docker tag
in28min/todo-rest-api-h2:1.0.0.RELEASE
in28min/todo-rest-api-h2:latest
docker pull MySQL
docker search mysql
docker run mysql
docker image history
f8049a029560
docker image
inspect f8049a029560
docker image (remove
from local)
Playing with Docker
containers:
docker container run -p
5000 :5000 in28min/todo-rest-api-h2:1.0.0-RELEASE
docker container pause
6478 (stop the container)
docker container unpause
6478
docker container inspect
6478
docker container prune
(it will remove all containers asking for Y/N if Y removed all)
docker container ls -a
STOP->SIGTERMÃ graceful shutdown
KillèSIGKILL=> immediately terminates the process
docker container ls
docker container logs -f
1b1
docker container ls
docker container stop
1b1 (Shutting down ExecutorService)
docker container kill
9b8
docker logs -f 9b8
docker container prune
docker container ls -a
docker container run -p
5000 :5000 -d --restart=always in28min/todo-rest-api-h2:1.0.0-RELEASE
(Restart Policy in Docker)
docker container stop
501
docker container ls -a
docker container ls (now
its running once restarted)
docker container stop
501
docker container prune
Playing with Docker
commands stats , System
Another tab :
docker events (CTRL+C
terminates Docker container)
Another window : docker container ls
docker container stop
c710
launch another container
$docker container run -p
5000 :5000 -d in28min/todo-rest-api-h2:0.0.1-SNAPSHOT
$docker top
$docker container ls
(give list of containers are active )
$docker top
a6d6cd317b4b
$docker stats (It will give size and Metrics of the
container Volume)
To add the specific
container Limit and Size and CPU QUOTA
$docker container run -p
5001 :5000 -m 512m -d
in28min/todo-rest-api-h2:0.0.1-SNAPSHOT
$docker container run -p
5001 :5000 -m 512m --cpu-quota
-d
in28min/todo-rest-api-h2:0.0.1-SNAPSHOT
100000 = 100% 5000 =
5%
$docker container run
-p 5001 :5000 -m 512m --cpu-quota 5000 -d
in28min/todo-rest-api-h2:0.0.1-SNAPSHOT
$docker container logs
-f 3fb
$docker container stop
3fb
$docker container run
-p 5001 :5000 -m 512m --cpu-quota 50000 -d
in28min/todo-rest-api-h2:0.0.1-SNAPSHOT
If
this stops it will take more time
$docker container stop
3a6db
$docker container system
df
$docker container stats
Introduction to
Distributed Tracing
·
Complex call chain
·
How do you debug problems?
·
How do you trace requests across microservices?
·
Entire Distributed Tracing
Distributed
tracing, also called distributed request tracing, is a method used to
profile and monitor applications, especially those built using a microservices
architecture. Distributed tracing helps pinpoint where failures occur and
what causes poor performance.
Launching Zipkin Container Using Docker
docker run -p 9411:9411 openzipkin/zipkin:2.23
Connecting Currency Exchange Microservice with Zipkin
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
Distributed Tracing
-Asynchronous
Connecting Currency Conversion Microservice & API
GATEWAY
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
All the above 3
dependencies need to be added in all microservices.
application.properties (API-GATEWAY)
spring.sleuth.sampler.probability=1.0
Start all 3 Services Manually (API-GATEWAY,
CURRENCY-CONVERSION-SERVICE, CURRENCY-EXCHANGE-SERVICE)
Link for the Next Lecture
In the next lecture, we will import projects into eclipse.
Here is the link to bookmark:
https://github.com/in28minutes/spring-microservices-v2/tree/main/04.docker
Creating Container Image for Currency Exchange Microservice
Step 1: To Create Container image below need to be added in
POM.xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>in28min/mmv2-${project.artifactId}:${project.version}</name>
</image>
<pullPolicyIF_NOT_PRESENT</pullPolicy>
</configuration>
</plugin>
</plugins>
</build>
Step 2 : Go to
Eclipse - > Select Project (currency-exchange-service) ->Run As Maven
build
Goals: spring-boot:build-image
-DskipTests ->Apply à Run
Building Image
‘docker.io/in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT’
Run the below command on docker container
$docker run -p 8000:8000 in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT
Getting Started with Docker Compose
Overview of
Docker Compose | Docker Documentation
docker-compose –version
1.27.4 build 40524192
Please add the below file with name “docker-compose.yaml”
file for below details for each microservice
version: ‘3.7’
services:
currency-exchange:
image: in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8000:8000”
networks:
- currency-network
networks:
- currency-network:
Run the below command
$docker compose up
Running Naming server with Docker Compose
Step 1: Please add the pom.xml for below details
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>in28min/mmv2-${project.artifactId}:${project.version}</name>
</image>
<pullPolicyIF_NOT_PRESENT</pullPolicy>
</configuration>
</plugin>
</plugins>
</build>
Step 2 : Go to
Eclipse - > Select Project (naming-server) ->Run As Maven build
Goals: spring-boot:build-image
-DskipTests ->Apply à Run
Building Image
‘docker.io/in28min/mmv2-naming-server:0.0.1-SNAPSHOT’
Step 3: add the Eureka Naming Server details in docker-compose.yaml
file
version: ‘3.7’
services:
currency-exchange:
image: in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8000:8000”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
naming-server:
image: in28min/mmv2-naming-server:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8761:8761”
networks:
- currency-network
networks:
- currency-network:
=====================================================================
Next step to run on docker container:=
$docker compose up
Running Currency
Conversion Microservice with Docker
Step 1: Please add the pom.xml for below details
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>in28min/mmv2-${project.artifactId}:${project.version}</name>
</image>
<pullPolicyIF_NOT_PRESENT</pullPolicy>
</configuration>
</plugin>
</plugins>
</build>
Step 2 : Go to
Eclipse - > Select Project (currency-conversion-service) ->Run As Maven
build
Goals: spring-boot:build-image
-DskipTests ->Apply à Run
Building Image
‘docker.io/in28min/mmv2-naming-server:0.0.1-SNAPSHOT’
Step 3: add the Eureka Naming Server details in docker-compose.yaml
file
version: ‘3.7’
services:
currency-exchange:
image: in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8000:8000”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
currency-conversion:
image: in28min/mmv2-currency-conversion-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8100:8100”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
naming-server:
image: in28min/mmv2-naming-server:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8761:8761”
networks:
- currency-network
networks:
-
currency-network:
=====================================================================
Running Spring Cloud API Gateway with Docker Compose
Step 1: Please add the pom.xml for below details
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>in28min/mmv2-${project.artifactId}:${project.version}</name>
</image>
<pullPolicyIF_NOT_PRESENT</pullPolicy>
</configuration>
</plugin>
</plugins>
</build>
Step 2 : Go to
Eclipse - > Select Project (currency-conversion-service) ->Run As Maven
build
Goals: spring-boot:build-image
-DskipTests ->Apply à Run
Building Image
‘docker.io/in28min/mmv2-api-gateway:0.0.1-SNAPSHOT’
Step 3: add the Eureka Naming Server details in docker-compose.yaml
file
version: ‘3.7’
services:
currency-exchange:
image: in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8000:8000”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
currency-conversion:
image: in28min/mmv2-currency-conversion-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8100:8100”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
api-gateway:
image: in28min/mmv2-api-gateway:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8765:8765”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
naming-server:
image: in28min/mmv2-naming-server:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8761:8761”
networks:
- currency-network
networks:
- currency-network:
=====================================================================
Debugging Problems with Docker Compose
Debugging microservices problems can be difficult as there
are multiple components involved.
Step by Step instructions is provided in the troubleshooting
guide to help you troubleshoot frequently occurring problems.
COMPLETE DEBUGGING GUIDE
TOP Recommendation from Debugging Guide:
(2) Try adding restart: always to zipkin-server in docker-compose.yaml
zipkin-server:
image:
openzipkin/zipkin:2.23
mem_limit: 300m
ports:
-
"9411:9411"
networks:
-
currency-network
environment:
RABBIT_URI:
amqp://guest:guest@rabbitmq:5672
depends_on:
- rabbitmq
restart: always
#Restart if there is a problem starting up
======================================================================
Running
Zipkin with Docker Compose
Below Steps need to be
added in “docker-compose.yaml” file
version: ‘3.7’
services:
currency-exchange:
image: in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8000:8000”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
currency-conversion:
image: in28min/mmv2-currency-conversion-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8100:8100”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
SPRING.ZIPKIN.BASEURL: http://zipkin-server
:9411/
api-gateway:
image: in28min/mmv2-api-gateway:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8765:8765”
networks:
- currency-network
depends_on:
-
naming-server
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
SPRING.ZIPKIN.BASEURL: http://zipkin-server
:9411/
naming-server:
image: in28min/mmv2-naming-server:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8761:8761”
networks:
- currency-network
#docker run -p
9411:9411 openzipkin/zipkin:2.23
zipkin-server:
image:
openzipkin/zipkin:2.23
mem_limit: 300m
ports:
-
“9411:9411”
networks:
- currency-network
networks:
- currency-network:
Running Zipkin and Rabbit MQ with Docker Compose
Below dependency need to add in POM.xml for RABBIT MQ
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
And Below property to be added in application.properties
file
##spring.zipkin.baseUrl=http://localhost:9411/
spring.zipkin.sender.type=rabbit
The rabbit MQ details need to be added “docker-compose.yaml
:file below
version: ‘3.7’
services:
currency-exchange:
image: in28min/mmv2-currency-exchange-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8000:8000”
networks:
- currency-network
depends_on:
-
naming-server
-
rabbitmq
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
SPRING.ZIPKIN.BASEURL: http://zipkin-server
:9411/
RABBIT_URI: amqp://guest:guest@rabbitmq:5672
SPRING_ZIPKIN_SENDER_TYPE: rabbit
currency-conversion:
image: in28min/mmv2-currency-conversion-service:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8100:8100”
networks:
-
currency-network
depends_on:
-
naming-server
-
rabbitmq
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
SPRING.ZIPKIN.BASEURL: http://zipkin-server
:9411/
RABBIT_URI: amqp://guest:guest@rabbitmq:5672
SPRING_ZIPKIN_SENDER_TYPE: rabbit
api-gateway:
image: in28min/mmv2-api-gateway:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8765:8765”
networks:
-
currency-network
depends_on:
-
naming-server
-
rabbitmq
environment:
EUREKA.CLIENT.SERVICEURL.DEFAULTZONE:
http://naming-server:8761/eureka
SPRING.ZIPKIN.BASEURL: http://zipkin-server
:9411/
RABBIT_URI: amqp://guest:guest@rabbitmq:5672
SPRING_ZIPKIN_SENDER_TYPE: rabbit
naming-server:
image: in28min/mmv2-naming-server:0.0.1-SNAPSHOT
mem_limit: 700m
ports:
-
“8761:8761”
networks:
-
currency-network
#docker run -p
9411:9411 openzipkin/zipkin:2.23
zipkin-server:
image:
openzipkin/zipkin:2.23
mem_limit: 300m
ports:
-
“9411:9411”
networks:
-
currency-network
environment
-
RABBIT_URI: amqp://guest:guest@rabbitmq:5672
depends_on
-
rabbitmq
rabbitmq:
image: rabbitmq:3.5.3-management
mem_limit: 300m
ports: “5672:5672”
“15672:15672”
networks:
-
currency-network
networks:
- currency-network:
====================================================================
Docker Kubernetes and Microservices
Create Docker images for each Microservice
Docker image contains everything a microservice needs to
run:
-
Application Runtime (JDK or Python NodeJS)
-
Application code
-
Dependencies
You can run the docker containers the same way on any
infrastructure
-
Your local machine
-
Corporate Data center
-
Cloud
Container Orchestration
Requirement : I want 10 instances of Microservice A container ,15 instances of Microservice B
container and ….
Typical Features :-
·
Auto Scaling : Scale containers based on
demand.
·
Service Discovery : Help Microservices
find one another
·
Load Balancer : Distribute load along multiple instances of
microservices
·
Self-Healing: Do health checks and
replace failing instances.
·
Zero Down time deployments : Release new
versions without downtime
Container Orchestration
Options
AWS
Specific
·
AWS
Elastic Container Service (ECS)
·
AWS
Fargate: Serverless version of AWS ECS.
Cloud
Neutral
·
Kubernetes
-
AWS
Elastic Kubernetes Service (EKS)
-
Azure
– Azure Kubernetes Service (AKS)
-
GCP
– Google Kubernetes Engine (GKE)
EKS/AKS
doesn’t have a free tiler!
We use GCP
and GKE!
$kubectl
create deployment hello-world-rest-api --image=in28min/hello-world-rest-api:0.0.1.RELEASE
$kubectl
expose deployment hello-world-rest-api --type=LoadBalancer --port=8080
$kubectl
scale deployment hello-world-rest-api –replicas=3
$kubectl
acutoscale deployment hello-world-rest-api --max=10
--cpu-percent=70
Commands executed in this section
Here's a backup of commands executed in this section!
Refer to these if you face any problems!
You can bookmark this
URL as well
https://github.com/in28minutes/spring-microservices-v2/tree/main/05.kubernetes#commands
1. docker run -p 8080:8080 in28min/hello-world-rest-api:0.0.1.RELEASE
2.
3. kubectl create deployment hello-world-rest-api --image=in28min/hello-world-rest-api:0.0.1.RELEASE
4. kubectl expose deployment hello-world-rest-api --type=LoadBalancer --port=8080
5. kubectl scale deployment hello-world-rest-api --replicas=3
6. kubectl delete pod hello-world-rest-api-58ff5dd898-62l9d
7. kubectl autoscale deployment hello-world-rest-api --max=10 --cpu-percent=70
8. kubectl edit deployment hello-world-rest-api #minReadySeconds: 15
9. kubectl set image
deployment hello-world-rest-api hello-world-rest-api=in28min/hello-world-rest-api:0.0.2.RELEASE
10.
11. gcloud container clusters get-credentials in28minutes-cluster --zone us-central1-a --project solid-course-258105
12. kubectl create deployment hello-world-rest-api --image=in28min/hello-world-rest-api:0.0.1.RELEASE
13. kubectl expose deployment hello-world-rest-api --type=LoadBalancer --port=8080
14. kubectl set image
deployment hello-world-rest-api hello-world-rest-api=DUMMY_IMAGE:TEST
15. kubectl get events --sort-by=.metadata.creationTimestamp
16. kubectl set image
deployment hello-world-rest-api hello-world-rest-api=in28min/hello-world-rest-api:0.0.2.RELEASE
17. kubectl get events --sort-by=.metadata.creationTimestamp
18. kubectl get
componentstatuses
19. kubectl get pods --all-namespaces
20.
21. kubectl get events
22. kubectl get pods
23. kubectl get replicaset
24. kubectl get deployment
25. kubectl get service
26.
27. kubectl get pods -o wide
28.
29. kubectl explain pods
30. kubectl get pods -o wide
31.
32. kubectl describe pod hello-world-rest-api-58ff5dd898-9trh2
33.
34. kubectl get replicasets
35. kubectl get replicaset
36.
37. kubectl scale deployment hello-world-rest-api --replicas=3
38. kubectl get pods
39. kubectl get replicaset
40. kubectl get events
41. kubectl get events --sort.by=.metadata.creationTimestamp
42.
43. kubectl get rs
44. kubectl get rs -o wide
45. kubectl set image
deployment hello-world-rest-api hello-world-rest-api=DUMMY_IMAGE:TEST
46. kubectl get rs -o wide
47. kubectl get pods
48. kubectl describe pod hello-world-rest-api-85995ddd5c-msjsm
49. kubectl get events --sort-by=.metadata.creationTimestamp
50.
51. kubectl set image
deployment hello-world-rest-api hello-world-rest-api=in28min/hello-world-rest-api:0.0.2.RELEASE
52. kubectl get events --sort-by=.metadata.creationTimestamp
53. kubectl get pods -o wide
54. kubectl delete pod hello-world-rest-api-67c79fd44f-n6c7l
55. kubectl get pods -o wide
56. kubectl delete pod hello-world-rest-api-67c79fd44f-8bhdt
57.
58. gcloud container clusters get-credentials in28minutes-cluster --zone us-central1-c --project solid-course-258105
59. docker login
60. docker push in28min/mmv2-currency-exchange-service:0.0.11-SNAPSHOT
61. docker push in28min/mmv2-currency-conversion-service:0.0.11-SNAPSHOT
62.
63. kubectl create deployment currency-exchange --image=in28min/mmv2-currency-exchange-service:0.0.11-SNAPSHOT
64. kubectl expose deployment currency-exchange --type=LoadBalancer --port=8000
65. kubectl get svc
66. kubectl get services
67. kubectl get pods
68. kubectl get po
69. kubectl get replicaset
70. kubectl get rs
71. kubectl get all
72.
73. kubectl create deployment currency-conversion --image=in28min/mmv2-currency-conversion-service:0.0.11-SNAPSHOT
74. kubectl expose deployment currency-conversion --type=LoadBalancer --port=8100
75.
76. kubectl get svc --watch
77.
78. kubectl get deployments
79.
80. kubectl get deployment
currency-exchange -o yaml >> deployment.yaml
81. kubectl get service
currency-exchange -o yaml >> service.yaml
82.
83. kubectl diff -f deployment.yaml
84. kubectl apply -f deployment.yaml
85.
86. kubectl delete all -l app=currency-exchange
87. kubectl delete all -l app=currency-conversion
88.
89. kubectl rollout history deployment currency-conversion
90. kubectl rollout history deployment currency-exchange
91. kubectl rollout undo deployment currency-exchange --to-revision=1
92.
93. kubectl logs currency-exchange-9fc6f979b-2gmn8
94. kubectl logs -f currency-exchange-9fc6f979b-2gmn8
95.
96. kubectl autoscale deployment currency-exchange --min=1 --max=3 --cpu-percent=5
97. kubectl get hpa
98.
99. kubectl top pod
100. kubectl top nodes
101. kubectl get hpa
102. kubectl delete hpa currency-exchange
103.
104. kubectl create configmap currency-conversion --from-literal=CURRENCY_EXCHANGE_URI=http://currency-exchange
105. kubectl get configmap
106.
107. kubectl get configmap
currency-conversion -o yaml >> configmap.yaml
108.
109. watch -n 0.1 curl http://34.66.241.150:8100/currency-conversion-feign/from/USD/to/INR/quantity/10
110.
111. docker push in28min/mmv2-currency-conversion-service:0.0.12-SNAPSHOT
112. docker push in28min/mmv2-currency-exchange-service:0.0.12-SNAPSHOT
113. kubectl get events
114. kubectl get pods
115. kubectl get replicaset
116. kubectl get deployments
117. kubectl get service
Understanding Pods
in Kubernetes
Without
POD we cannot create a container in Kubernetes
$kubectl
get pods -o wide
$kubectl
describe pod hello-world-rest-api-58ff5ddd898
$kubectl
get replicasets
$kubectl
get rs
$kubectl
scale deployment hello-world-rest-api -–replicas=3
$kubectl
get pods
Understanding of
Deployments / Replicasets in Kubernetes
$kubectl
get rs
$kubectl
get rs -o wide
$kubectl
get pods
$kubectl
set image deployment hello-world-rest-api hello-world-rest-api=DUMMY_IMAGE:TEST (Invalid Image Name)
$kubectl
get rs -o wide
$kubectl
get pods
$kubectl
get events –-sort-by=.metadata.creationTimestamp
$kubectl set image deployment hello-world-rest-api
hello-world-rest-api=in28min/hello-world-rest-api:0.0.2.RELEASE
Understanding
Services in Kubernetes
Kubernetes provides an easy way to scale your application,
compared to virtual machines. It keeps code operational and speeds up the
delivery process. Kubernetes API allows automating a lot of resource management
and provisioning tasks.
Do we really
need Kubernetes?
Kubernetes
is useful if you are dealing with many containers and require some automation
of the steps when starting them. So, unless you have a large microservice
environment, Kubernetes is unlikely to bring much added value. Probably,
it is not needed or suited for your case and you should not invest in it.
Why do we need Kubernetes over Docker?
While the promise of containers is to code once and run
anywhere, Kubernetes provides the potential to orchestrate and manage
all your container resources from a single control plane. It helps with
networking, load-balancing, security, and scaling across all Kubernetes nodes
which runs your containers.
Why do we need containers?
Containers allow applications to be more rapidly
deployed, patched, or scaled. Containers support agile and DevOps efforts
to accelerate development, test, and production cycles.
What is
Kubernetes in simple words?
Kubernetes
is a system that manages containers (containerized applications) where
a container could be explained as a lightweight virtual machine. To build
an application you need to build a bunch of containers and then use Kubernetes
to manage those containers.
$kubectl get pods -o wide
$kubectl delete
pod hello-world-rest-api-67c79fd44f-n6c71
$kubectl get
pods -o wide
$kubectl get
services
There is one
more type of service called Node Port . we will talk about it a little later!
Understand the Kubernetes Architecture – Master Node and Nodes
$kubectl get
componentstatuses
Install
GCloud
https://cloud.google.com/sdk/install
Installing
Kubectl
Before installing we would recommend seeing if you have
kubectl from docker desktop -Run “kubectl –version” to check In command
prompt/terminal
Link for the Next
Lecture
In the
next lecture, we will import projects into eclipse.
Here is
the link to bookmark:
https://github.com/in28minutes/spring-microservices-v2/tree/main/05.kubernetes
Deploy Microservices to Kubernetes &Understand Services
$kubectl create
deployment currency-exchange –-image=in28min/mmv2-currency-exchange-service:0.0.11.SNAPSHOT
http://localhost:8000/currency-exchange/from/USD/to/INR
Curl http://34.66.241.150:8000/currency-exchange/from/USD/to/INR
$kubectl get svc
$kubectl get
pods
$kubectl get
replicasets
$kubectl get rs
$kubectl get all
$kubectl create
deployment currency-conversion –-image=in28min/mmv2-currency-conversion-service:0.0.11.SNAPSHOT
$kubectl get svc
–-watch
http://localhost:8100/currency-conversion-feign/from/USD/to/INR/quantity/10
Curl http://34.67.33.185:8100/currency-conversion-feign/from/USD/to/INR/quantity/10
CURRENCY_CONVERSION_SERVICE_HOST
CURRENCY_EXCHANGE_SERVICE_HOST
SERVICE_NAME_HOST
Creating Declarative Configuration Kubernetes YAML for
Microservice
$kubectl get
service
$kubectl get
deployments
$kubectl get
deployment currency-exchange -o yaml
$kubectl get
deployment currency-exchange -o yaml
>> deployment.yaml
$kubectl get
service currency-exchange -o yaml
>>service.yaml
Both files can copy
into deployment.yaml file with ----
after service.yaml content should be added
$kubectl diff -f
deployment.yaml
$kubectl apply
-f deployment.yaml
$kubectl get
pods
Cleanup
Kubernetes YAML for Microservices
Enable Logging and Tracing APIs
in Google Cloud Platform
https://console.cloud.google.com/apis/library?authuser=3&project=solid-course-2581055=stackdriver
Deploying Microservices using Kubernetes YAML Configuration
$kubectl delete
all -l app=currency-exchange
$kubectl delete
all -l app=currency-conversion
pwd
$kubectl get all
$kubectl apply
-f deployment.yaml
$kubectl delete
all -l app=currency-exchange
$kubectl get
pods
$kubectl get svc
–-watch
Same the above
for currency-exchange service
Creating Environment variables to Enable Microservices
Communication
//CHANGE-KUBERNETES
// @FeignClient(name = "currency-exchange", url =
"${CURRENCY_EXCHANGE_SERVICE_HOST:http://localhost}:8000")
@FeignClient(name = "currency-exchange", url =
"${CURRENCY_EXCHANGE_URI:http://localhost}:8000")
public interface CurrencyExchangeProxy {}
-
CURRENCY_CONVERSION_URI
-
SERVICE_NAME_URI
$docker push
in28min/mmv2-currency-conversion-service:0.0.12-SNAPSHOT
$docker push
in28min/mmv2-currency-exchange-service:0.0.12-SNAPSHOT
Both should deploy together
$kubectl get svc –-watch
$kubectl apply -f deployment.yaml
$kubectl get service
currency-exchange (changes to be add in env: with name , value in deployment.yaml file)
env:
-
name: CURRENCY_EXCHANGE_URI
value:
http://currency-exchange
env:
-
name: CURRENCY_CONVERSION_URI
value: http://currency-conversion
$kubectl get diff -f deployment.yaml
$kubectl get pods
Understanding Centralized Configuration in Kubernetes – Config
Maps
$kubectl create configmap currency-conversion
–-from-literal = CURRENCY_EXCHANGE_URI=http://currency-exchange
$kubectl get configmap
$kubectl get configmap currency-conversion
$kubectl get configmap currency-conversion -o yaml
$kubectl get configmap currency-conversion -o yaml >>
configmap.yaml
$kubectl get configmap currency-conversion -o yaml **(here
confimap.yaml details to add in deployment.yaml file)
envFrom:
-
confingMapRef:
name: currency-conversion
$kubectl apply -f deployment.yaml
Exploring Centralized Logging and Monitoring in GKE
API
Library – APIs and services – Google Cloud Platform
$kubectl get svc –-watch
Exploring Microservices Deployments with Kubernetes
$kubectl rollout history deployment currency-conversion
$kubectl rollout history deployment currency-exchange
$kubectl rollout undo deployment currency-exchange --to-revision=1
$kubectl logs -f
currency-exchange-686bbff8dc-vz76j
Configuring Liveness and Readiness Probes for Microservices with
K8S (Kubernetes)
Kubernetes uses probes to check the health of a microservice
:
-
If readiness probe is not successful , no
traffic is sent
-
If live probe is not successful , pod is
restarted
Spring Boot actuator (>=2.3) provides inbuilt readiness
of liveness probes:
-
/health/readiness
-
/health/liveness
$kubectl diff -f deployment.yaml
Readiness to be added in deployment.yaml
readinessProbe:
httpGet:
port: 8000
path:
/actuator/health/readiness
livenessProbe:
httpGet:
port: 8000
path:
/actuator/health/liveness
restartPolicy:
Always
$kubectl apply -f deployment.yaml
$kubectl get pods
Auto
Scaling Microservices with Kubernetes
$kubectl scale deployment currency-exchange –replicas=2
spec:
replicas: 1
selector:
matchLabels:
app:
currency-exchange
$kubectl autoscale deployment
currency-exchange –-min =1 ---max =3 –cpu—-percent=70
$kubectl autoscale deployment
currency-exchange –-min =1 ---max =3 –cpu—-percent=5
Horizontal pod autoscaler (hpa)
Kubernetes supports 3 different types of autoscaling
·
Vertical Pod Autoscaler (VPA) : Increases
or decrease the resource limits on the pod
·
Horizontal Pod Autoscaler(HPA) :
Increases or decreases the number of pod instances.
·
Cluster Autoscaler (CA) : Increases or decreases the nodes on the
node pool. Based on pod scheduling
$kubectl get hpa
$kubectl get pods
$kubectl get services
$kubectl describe hpa
$kubectl get hpa -w
$kubectl port -forward
src/microsvc 8080:8080
$kubectl autoscale deployment php-apache --cpu percent=50 --min=1
--max=4
$kubectl delete hpa currency-exchange (“”delete””)
Spring DATA JPA
H2 Database URL
With the latest versions of Spring Boot (2.3+), the H2 database
name is randomly generated each time you restart the server.
You can find the database name and URL from the console log.
RECOMMENDED:
Make the database URL a constant by configuring this
in application.properties
.
1.
spring.datasource.url=jdbc:h2:mem:testdb
2.
spring.data.jpa.repositories.bootstrap-mode=default
DEBUGGING GUIDE (If you have problems)
JPA Hibernate Debugging Guide: https://github.com/in28minutes/in28minutes-initiatives/blob/master/The-in28Minutes-TroubleshootingGuide-And-FAQ/jpa-and-hibernate.md
Why do we need to configure bootstrap-mode? Details
here - https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#bootstrapmode-for-jpa-repositories
Dependency Injection (DI) in Spring & Spring Boot
Microservices
Dependency
Injection (DI) is a core feature of the Spring framework that enables loose
coupling and enhances testability by injecting dependencies rather than
hardcoding them. DI in Spring and Spring Boot microservices is typically managed
using annotations.
Types of Dependency Injection in
Spring & Spring Boot
Spring
provides three primary ways to perform DI:
a)
Constructor Injection (Recommended)
·
Dependencies are injected through
the constructor.
·
Ensures immutability and supports
unit testing.
@Component
public class OrderService {
private final PaymentService
paymentService;
@Autowired
// Optional in Spring Boot (since Spring 4.3+)
public OrderService(PaymentService
paymentService) {
this.paymentService = paymentService;
}
}
b)
Setter Injection
·
Dependencies are injected using
setter methods.
·
Useful when optional dependencies
are involved.
@Component
public class OrderService {
private PaymentService
paymentService;
@Autowired
public void
setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
c)
Field Injection (Not Recommended)
·
Directly injects dependencies
into fields using @Autowired.
·
Harder to test and violates Dependency
Injection principles.
@Component
public class OrderService {
@Autowired
private PaymentService
paymentService;
}
2.
Annotations for Dependency Injection
Spring
provides various annotations for managing DI:
Annotation |
Description |
@Component |
Marks a class as a
Spring-managed component. |
@Service |
Specialization of @Component,
used for service layer components. |
@Repository |
Specialization of @Component,
used for DAO/repository classes. |
@Controller |
Marks a class as a Spring MVC controller. |
@RestController |
Combines @Controller and
@ResponseBody for REST APIs. |
@Autowired |
Injects dependencies
automatically. |
@Qualifier |
Specifies the exact bean to
inject when multiple candidates exist. |
@Primary |
Marks a bean as the primary
choice when multiple beans exist. |
@Bean |
Declares a bean inside a
@Configuration class. |
@Scope |
Defines the scope of a bean
(e.g., singleton, prototype). |
Dependency Injection in Spring Boot Microservices
In
a microservices architecture, different services interact with each other. DI
is widely used in:
1. Service Layer - Injecting business logic services.
2. Repository Layer - Injecting database repositories.
3. Rest Clients (Feign, RestTemplate, WebClient) - Injecting HTTP clients for inter-service
communication.
4. Configuration Properties - Injecting properties from application.yml.
Example:
DI in a Microservice
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderService orderService;
@Autowired
public OrderController(OrderService
orderService) {
this.orderService = orderService;
}
@GetMapping("/{id}")
public Order getOrder(@PathVariable Long
id) {
return orderService.getOrderById(id);
}
}
Feign
Client DI Example
@FeignClient(name =
"payment-service", url = "http://localhost:8081")
public interface PaymentClient {
@GetMapping("/payments/{orderId}")
Payment getPaymentByOrderId(@PathVariable
Long orderId);
}
@Service
public class OrderService {
private final PaymentClient
paymentClient;
@Autowired
public OrderService(PaymentClient
paymentClient) {
this.paymentClient =
paymentClient;
}
}
4.
Dependency Injection Best Practices in Microservices
✔ Prefer
Constructor Injection - Ensures immutability and testability.
✔ Use @Qualifier When Multiple Beans Exist
- Helps in resolving bean conflicts.
✔ Avoid Field Injection - Harder to test and manage.
✔ Use Configuration Properties - Inject
values from application.yml.
✔ Leverage Spring Boot Auto-Configuration
- Reduces manual bean creation
What is the diff between Normal Singleton Java class and Spring Singleton?
The
difference between a normal Singleton Java class and a Spring Singleton bean
lies in their scope, lifecycle management, and thread safety.
1.
Normal Singleton Java Class
·
Implemented using static instance
and private constructor.
·
Ensures only one instance is
created per JVM.
·
The developer is responsible for
managing lifecycle, synchronization, and ensuring thread safety.
Common
implementations:
public class Singleton {
private static Singleton
instance;
private Singleton() {}
public static Singleton getInstance()
{
if (instance == null) {
synchronized
(Singleton.class) {
if (instance == null) {
instance = new
Singleton();
}
}
}
return instance;
}
}
Limitations:
o Hard to manage dependencies.
o Manual control over lifecycle.
o Cannot leverage features like dependency
injection.
2.
Spring Singleton Bean
·
Managed by Spring Container, not
manually instantiated.
·
Single instance per Spring
container (ApplicationContext), not per JVM.
·
Defined in Spring configuration
(@Component, @Bean, @Service, etc.).
·
Can be injected into other beans
using Dependency Injection.
Example:
@Component
public class SpringSingleton {
}
·
By default, Spring beans are
singleton-scoped (@Scope("singleton") is implicit).
·
Unlike normal Java singleton,
multiple instances can exist if there are multiple Spring containers.
Key
Differences
Feature |
Normal
Singleton Java Class |
Spring
Singleton Bean |
Instance Scope |
One per JVM |
One per Spring container |
Thread Safety |
Developer must handle |
Managed by Spring |
Lifecycle |
Developer controls |
Managed by Spring |
Dependency Injection |
Not possible |
Supported |
Configuration |
Implemented manually |
Configured via annotations/XML |
Conclusion
·
If you need a globally accessible
instance (like a cache manager), use normal Singleton.
·
If you need Spring-managed
components with DI, use Spring Singleton.
How to handle exceptions in
springboot & microservices?
Handling
Exceptions in Spring Boot & Microservices
In
Spring Boot & Microservices, exception handling is crucial to ensure that
errors are properly managed and meaningful responses are sent back to clients.
Below are different ways to handle exceptions effectively:
1.
Using @ExceptionHandler (Local Exception Handling)
This
is used to handle exceptions at the controller level.
Example:
Handling a Custom Exception in a Controller
@RestController
@RequestMapping("/products")
public
class ProductController {
@GetMapping("/{id}")
public Product getProduct(@PathVariable
Long id) {
return
productService.getProductById(id)
.orElseThrow(() -> new
ProductNotFoundException("Product not found with ID: " + id));
}
@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<String>
handleProductNotFoundException(ProductNotFoundException ex) {
return new
ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
}
📌 Best for: Handling specific exceptions
within a single controller.
2.
Using @ControllerAdvice (Global Exception Handling)
This
is used to handle exceptions globally across all controllers.
Example:
Global Exception Handler
@RestControllerAdvice
public
class GlobalExceptionHandler {
@ExceptionHandler(ProductNotFoundException.class)
public ResponseEntity<ErrorResponse>
handleProductNotFoundException(ProductNotFoundException ex) {
ErrorResponse errorResponse = new
ErrorResponse(LocalDateTime.now(), ex.getMessage(),
HttpStatus.NOT_FOUND.value());
return new
ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse>
handleGenericException(Exception ex) {
ErrorResponse errorResponse = new
ErrorResponse(LocalDateTime.now(), "Internal Server Error",
HttpStatus.INTERNAL_SERVER_ERROR.value());
return new
ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Error
Response DTO
public
class ErrorResponse {
private LocalDateTime timestamp;
private String message;
private int status;
public ErrorResponse(LocalDateTime
timestamp, String message, int status) {
this.timestamp = timestamp;
this.message = message;
this.status = status;
}
// Getters and Setters
}
📌 Best for: Centralized handling of multiple
exceptions across microservices.
3.
Using @ResponseStatus for Custom Exceptions
You
can create custom exceptions and map them to specific HTTP status codes.
Example:
Custom Exception with @ResponseStatus
@ResponseStatus(HttpStatus.NOT_FOUND)
public
class ProductNotFoundException extends RuntimeException {
public ProductNotFoundException(String
message) {
super(message);
}
}
📌 Best for: Simple exception handling without
needing a centralized handler.
4.
Handling Validation Errors (@Valid)
When
using Spring Boot Validation (e.g., @Valid with DTOs), handle errors like this:
Example:
Handling Validation Errors
@ExceptionHandler(MethodArgumentNotValidException.class)
public
ResponseEntity<Map<String, String>>
handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new
HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage()));
return new ResponseEntity<>(errors,
HttpStatus.BAD_REQUEST);
}
📌 Best for: Handling form validation errors in
REST APIs.
5.
Using Filter for Exception Handling (For Security Issues)
For
filter-level exception handling (useful for authentication/authorization
issues):
Example:
Exception Handling in Filter
@Component
public
class JwtExceptionFilter extends OncePerRequestFilter {
@Override
protected void
doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain chain)
throws ServletException,
IOException {
try {
chain.doFilter(request, response);
} catch (JwtException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid
JWT Token");
}
}
}
📌 Best for: Handling authentication-related
exceptions in security filters.
6.
Handling Exceptions in Feign Clients (Microservices)
When
calling another microservice using Feign Client, handle exceptions properly.
Example:
Handling Feign Client Errors
@FeignClient(name
= "order-service", fallback = OrderFallback.class)
public
interface OrderClient {
@GetMapping("/orders/{id}")
Order getOrderById(@PathVariable Long id);
}
@Component
public
class OrderFallback implements OrderClient {
@Override
public Order getOrderById(Long id) {
return new Order(id, "Default
Order", "Service Down");
}
}
📌 Best for: Handling failures when
communicating between microservices.
7.
Handling Exceptions in Spring Boot @Async Methods
If
you have an asynchronous method using @Async, exceptions won't be propagated
unless explicitly handled.
Example:
Handling Async Exceptions
@Async
public
CompletableFuture<String> asyncMethod() {
try {
Thread.sleep(1000);
return
CompletableFuture.completedFuture("Success");
} catch (Exception e) {
return
CompletableFuture.failedFuture(new CustomException("Async error
occurred"));
}
}
📌 Best for: Handling errors in async service
methods.
8.
Logging Exceptions in Microservices
Use
Spring Boot Logging with @Slf4j for better debugging.
@Slf4j
@RestControllerAdvice
public
class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse>
handleGenericException(Exception ex) {
log.error("Error occurred:
{}", ex.getMessage(), ex);
return new ResponseEntity<>(new
ErrorResponse(LocalDateTime.now(), "Internal Server Error", 500),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
📌 Best for: Logging errors efficiently for
debugging in microservices.
Conclusion
🔹 Use @ExceptionHandler for handling specific
exceptions in controllers.
🔹 Use @ControllerAdvice for global exception
handling.
🔹 Use @ResponseStatus for defining custom
exceptions.
🔹 Handle validation errors properly using
@Valid.
🔹 Handle Feign Client failures for
inter-service communication.
🔹 Use filters for handling security-related
exceptions.
🔹 Log exceptions properly to track issues in
microservices.
Difference between String and
StringBuffer in Java
Feature |
String
(Immutable) |
StringBuffer
(Mutable) |
Mutability |
Immutable (once created, cannot
be changed) |
Mutable (can be modified
without creating a new object) |
Performance |
Slower (creates a new object
for every modification) |
Faster (modifications happen on
the same object) |
Thread-Safety |
Thread-safe because of
immutability |
Thread-safe (synchronized
methods) |
Memory
Usage |
High (new objects are created
for modifications) |
Efficient (modifications occur
in the same memory space) |
Usage |
When string content doesn't
change frequently |
When frequent string
modifications are needed |
Example Usage :
// String (Immutable)
String s1 = "Hello";
s1 = s1 + " World"; // Creates a new object
System.out.println(s1); // Output: Hello World
// StringBuffer (Mutable)
StringBuffer sb = new
StringBuffer("Hello");
sb.append(" World"); // Modifies existing object
System.out.println(sb); // Output: Hello World
📌 Use String when values are constant, use
StringBuffer when frequent modifications are needed.
What is SCP (String Constant
Pool)?
SCP (String Constant Pool) is a special memory area in the Heap
Memory where Java stores String literals to optimize memory usage.
How SCP Works
String s1 = "Hello";
String s2 = "Hello"; //
Uses the same object from SCP
String s3 = new
String("Hello"); // Creates a new object in Heap (not SCP)
·
s1 and s2 refer to the same
object in SCP.
·
s3 creates a new object in
the Heap memory.
📌 SCP helps reduce memory overhead by
reusing string literals.
No comments:
Post a Comment