Wednesday, April 9, 2025

Microservices Overview

 

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.

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

http://start.spring.io

 

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

https://github.com/in28minutes/spring-microservices/blob/master/02.restful-web-services/2.3.1.RELEASE-upgrade.md

 

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

http://server/getPosts

http://server/deletePosts

http://server/doThis

Level -1 : EXPOSE RESOURCES WITH PROPER URI

http://server/accounts

http://server/accounts/10

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

http://localhost:8761/

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

http://localhost:9411/zipkin/

Spring Cloud Bus Refresh

http://localhost:8080/actuator/bus-refresh (POST)

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 NEWSWe 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.

 

https://github.com/in28minutes/in28minutes-initiatives/tree/master/The-in28Minutes-TroubleshootingGuide-And-FAQ#debugging-problems-with-feign-and-ribbon

 

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.

https://github.com/in28minutes/in28minutes-initiatives/tree/master/The-in28Minutes-TroubleshootingGuide-And-FAQ#debugging-problems-with-naming-server-eureka-and-ribbon

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 RoundRobinRuleAvailabilityFilteringRuleWeightedResponseTimeRule 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

http://localhost:8765/currency-conversion-service/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.

https://github.com/in28minutes/in28minutes-initiatives/tree/master/The-in28Minutes-TroubleshootingGuide-And-FAQ#debugging-problems-with-zuul-api-gateway

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>

in28minutes-initiatives/The-in28Minutes-TroubleshootingGuide-And-FAQ at master · in28minutes/in28minutes-initiatives · GitHub

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.

https://github.com/in28minutes/in28minutes-initiatives/tree/master/The-in28Minutes-TroubleshootingGuide-And-FAQ#debugging-problems-with-zipkin

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

  1. <dependency>  
  2. <groupId>org.springframework.cloud</groupId>  
  3. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>  
  4. </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

http://localhost:8761

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

localhost:8765/get

COMPLETE DEBUGGING GUIDE

https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/01-step-by-step-changes/microservices-v2-1.md#spring-cloud-api-gateway---step-22-to-step-25

 

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

3.       Introduction (readme.io)

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

 

https://hub.docker.com

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 Hub

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

https://github.com/in28minutes/spring-microservices-v2/blob/main/03.microservices/01-step-by-step-changes/microservices-v2-1.md#docker-section---connect-microservices-with-zipkin

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

Install Tools | Kubernetes

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_EXCHANGE_URI

-          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

Java 9 and Java11 and Java17, Java 21 Features

 Java 9 and Java11 and Java17 features along with explanation and examples in realtime scenarios Here's a detailed breakdown of Java 9, ...