Microservices with Spring Boot and Spring Cloud

Yat Man, Wong
14 min readApr 1, 2022

--

Random Picture

https://www.udemy.com/course/microservices-with-spring-boot-and-spring-cloud/learn/lecture/8005594#overview

Web Service

  • Definition: Software designed to support interoperable machine-to-machine interaction over a network
  • service definition should define:
    * request responses format
    * request structure
    * response structure
    * endpoint
  • transport define how a service is called
    * over HTTP or MQ (queue)

transport define how a service is called

  • over HTTP or MQ (queue)

SOAP (simple object access protocol)

  • restriction on format of xml that is exchange between service provider and service consumer
  • soap define a specific xml request and response structure
  • must have an envelope, header and body structure
  • no restuction on transport, can use http or MQ

Restful (Representation State Transfer)

  • A term coined by Roy Fielding, the person who developed http protocol
  • architecture style
  • Make the best use of http, use http to define the header and body, use http status code
  • think in term of resources, define resources using concept already exist in http
  • no restriction on data exchange format
  • Must use HTTP for transport

JPA (Java Persistent API)

  • Map Java object to SQL entry
  • Without JPA, JDBC requires you to write query and write preparedStatement, which is difficult to maintain when table change
  • JPA uses annotations like @Inheritance, @ManytoMany to map object to table
  • JPA define the annotations and specify relationship. Hibernate provides the implementation.

Entity

  • require a default no paramter constructor

Service

  • a class to manage entity (save entity etc)
  • Whenever we want to interacte with the database we need to be inside a transaction
  • entityManager persist object

CommandLineRunner

  • auto run by Spring as app start
  • has a run method that we can do the insert action

Repository

  • service is too repetitive if you have many entity ( similiar insert logic)
  • repository is an interface that JPA will provide the implementation
  • provide save() findbyId() method etc
  • replace service

Restful web service

  • start a spring project at start.spring.io
  • Some useful dependencies
  • Spring Web
  • Spring Boot DevTools
  • Spring Data JPA
  • H2 Database (in memory database)

Controller

  • controller handle http request (map method)
  • use annotation like @RequestMapping(method = RequestMethod.GET, path = “/helloWorld”
  • there is a short version: @GetMapping(path = x)
  • To return an object(bean) in api response, the class must have getter for its property
  • dispatcher servlet find the right controller to execute a request
  • ResponseEntity response a status code (Step10)
  • throw a exception with annotation to reurn error status like 404
  • create a class extends from ResponseEntityExceptionHandler to make all controller return standard error response (Step12)

Validation

  • check input is correct when calling api
  • add annotation like @Size @Past
  • In order to give api consumer useful message with validation fail, override the method handleMethodArgumentNotValid from ResponseEntityExceptionHandler (step15)

HATEOAS (Hypermedia as the Engine of Application State)

  • make the api return data as well as return different actions we can perform on the data
  • client make a request, and the next steps are handed to them in the response
  • provides additional links to the request along with the response
  • hard to maintain a list of links if we manually hard code them
  • return EntityModel of <data> (step 15 5:25)

Internationalization (i18)

  • customize language base on country
  • during request, api cosumer can specify the language in header
  • Accept-Language: fr
  • add a new paramter call “locale” in controller method
  • to avoid passing in locale in all parameter, we can read locale directly in LocaleContextHolder
  • pick value in property files instead of hard coding response
  • use messageSource to return value from property file

Content Negotiation

  • specify return xml or json response
  • api consumer speciy in header
  • Accept: Application/xml
  • automatically handle by spring boot when adding dependency com.fasterxml.jackson.dataformat

Swagger

  • documentation that is automatically generated from code, to avoid maintance
  • add dependency springdoc-openapi-ui
  • type localhost:8080/swagger-ui.html

Actuator

  • use for monitoring purpose, expose a bunch of url
  • implement services that return response to these url

HAL Explorer

  • provide a UI to navigate through the HATEOS and actuator links

Filtering

  • When return a object from Get Request, we can filter some fields using @JsonIgnore on the field or on the class
  • For dynamic filtering(filter different combinations of fields in different request), we can define MappingJacksonValue mapping
  • step 25 (4:01)

Versioning

  • Create two versions of the same service — step 27 (1:30)
  • a basic way is to having different url for the request, call uri versioning
  • another way is let client pass in a parameter, call request parameter versioning
  • can use header parameter as well, call header versioning
  • use the produces paramter (5:04). call accept header versioning / mime type versioning
  • header versioning are harder to document because they are not automatically generted by swagger

Authentication

  • Spring boot provided a basic security dependency
  • When using it, change authenticaion to basic authentication and pass in the password copied from log
  • change to custom password in local.properties

Richardson Maturity Model

  • how restful is your service
  • level 0: Expose SOAP web services in rest style
  • level 1: Expose resources with proper URI
  • level 2: level 1 + http protocal
  • level 3: level 2 + HATEOAS

Web Service Best Practice

  • Consumer first (documente help)
  • make best use of http
  • use http response code status
  • No secure Info in URL
  • Use Plurals
  • Use nouns for resources (For exceptions, define a consistent approach)

Microservices

  • Style to developmening a single application as a suite of small services
  • These services are independently deployable
  • REST
  • Small well chosen deployable unit
  • cloud enabled (have multiple deployed instance of the same service)

Advantage

  • Adapte new technology and process easily
  • Each microservices can be built with different technoloy
  • Dynamic Scaling
  • Faster release cycles
  • because we are developing smaller component

Challenge

  • Bounded Context
  • How to identity the boundary for each micro services?
  • it is an evolutionary process base on the knowledge we have at that time
  • Configuration managment
  • multiple instance & enviornment
  • Dynamic scale up and down
  • Visibility
  • How to locate bug when you have so many micro services
  • Pack of cards
  • If one microservice go down, all the other micro services that depend on it also go down

Spring Cloud

  • Spring cloud provides solution to the challenges above
  • Configuration managment
  • Spring Cloud Config Server
  • Store all configuration in a git repo and SpringCloudConfigServer will expose the config to the services
  • Dynamic scale up and down
  • Ribbon Load Balancing
  • distrubte load among all services
  • Naming Server has 2 important feature
  • all microservices register with the naming server
  • provide url of the available instance of services for service
  • Visibility and monitoring
  • Ziplin Distributed Tracing
  • trace a request across multiple components
  • Netflix API Gateway
  • Don’t have to implement basic features like logging in every microservice
  • Fault tolerance (Pack of cards)
  • Hystrix
  • Configure a default response when a service is down

Microservices with spring cloud

  • Give your microservice a good name in local.properties
  • spring.application.name=””
  • server.port=8888

Pick up value from application.properties

  • Create a configuration class with @ConfigurationProperties

Spring Cloud Config Server

Setting up Dynamic Port in the Response

  • We can run multiple instances of the same microservices by specifying the port number in IDE’s Run Configurations
  • (Step 12 4:16) Go to VM arguments -Dserver.port=8001., will override what is in application.properties
  • There is a class call Enviornment that we can get the port and pass back in response if needed

Feign

  • To call one microservice from another microservice
  • Without Feign: return a RestTemplate with the other service’s url (step 17 4:59)
  • (step 18) Create a Proxy interface and just call the method of that proxy in controller

Eureka Naming Server (Service Registery)

  • For different instances of the microservices, we don’t want to hard code the url:port because they might went down
  • This naming server itself is another microservices (Step 19)
  • Don’t register Eureka with itself (setting in local.properties)
  • Once up we can launch UI in localhost:{port} and see what is registered with Eureka
  • For a microservices to register with Eureka: import start-netflix-eureka-client
  • “Add the dependency is all you need to connect with Eureka”

Load Balancing

  • In the Feign proxy interface, if we do not specify a url:
  • Feign will talk to Eureka and pick up the instances of service and do load balancing automatically (step 22 -148)
  • spring cloud starter load balancer is a dependency imported from eureka dependency

Spring cloud API Gateway

  • An application could have hundreds of microservices and they have similiar features like authentication, authorization, logging, rate limiting, monitoring
  • API gateway is solution and Spring cloud gateway is recommended dependency
  • It is its own microservice with eureka and gateway dependency (step 22–149)
  • you can implement all the common features in API gateway and the API gateway would take care of the common features and invoke the intented microservice (step23)
  • “entry point” to your backend
  • Custom Routes
  • Create configuration class to redirect incoming request to url
  • to find url from naming server use lib:// (step 24 9:00)
  • You can match request by url or base on query, etc
  • Logging Filter
  • You can have a separate class only to filter all request and log them out (step 25)

Resilience4j (Circuit Breaker)

  • When one microservice depend on another like a chain, if one of them in the middle is down or slow it will affect others depend on it
  • It is its own microservice
  • If one microservice is having problem, instead of keep hitting it with request, return some default result back
  • retry
  • Have a retry annotation default retry 3 times if any exception happen, if 3 times all failed only then it will return an error back
  • To control retry behavior, configure setting in local.properteis (step 27 5:25)
  • allow waiting time between retry and exponential waiting
  • retry annotation also take in a fallback method
  • circuit breaker
  • Have a circuit breaker annotation (step 28)
  • if a response is failing repeatedly, it return a default respond instead of calling the dependency
  • a circuit breaker can be a 3 states, close, open, half open
  • close state (no problem, always be calling the dependency)
  • open state(service down, directly return default)
  • half open(send a percentage of request)
  • to move from open to half open, there is a wait duration setting
  • if half open request success go back to close state, other wise go to open state
  • Rate limiting
  • there is a rate limiting annotation
  • configure the limit in local.properties (step 29 2:10)
  • the request over the rate limit will get an error
  • BulkHead
  • how many concurrent calls are allow
  • there is a bulkhead annotation
  • change the concurrent call number in local.properteis (step 29 4:52)

Web Service

  • Definition: Software designed to support interoperable machine-to-machine interaction over a network
  • service definition should define
  • request responses format
  • request structure
  • response structure
  • endpoint
  • transport define how a service is called
  • over HTTP or MQ (queue)

SOAP (simple object access protocol)

  • restriction on format of xml that is exchange between service provider and service consumer
  • soap define a specific xml request and response structure
  • must have an envelope, header and body structure
  • no restuction on transport, can use http or MQ

Restful (Representation State Transfer)

  • A term coined by Roy Fielding, the person who developed http protocol
  • architecture style
  • Make the best use of http, use http to define the header and body, use http status code
  • think in term of resources, define resources using concept already exist in http
  • no restriction on data exchange format
  • Must use HTTP for transport

JPA (Java Persistent API)

  • Map Java object to SQL entry
  • Without JPA, JDBC requires you to write query and write preparedStatement, which is difficult to maintain when table change
  • JPA uses annotations like @Inheritance, @ManytoMany to map object to table
  • JPA define the annotations and specify relationship. Hibernate provides the implementation.

Entity

  • require a default no paramter constructor

Service

  • a class to manage entity (save entity etc)
  • Whenever we want to interacte with the database we need to be inside a transaction
  • entityManager persist object

CommandLineRunner

  • auto run by Spring as app start
  • has a run method that we can do the insert action

Repository

  • service is too repetitive if you have many entity ( similiar insert logic)
  • repository is an interface that JPA will provide the implementation
  • provide save() findbyId() method etc
  • replace service

Restful web service

  • start a spring project at start.spring.io
  • Some useful dependencies
  • Spring Web
  • Spring Boot DevTools
  • Spring Data JPA
  • H2 Database (in memory database)

Controller

  • controller handle http request (map method)
  • use annotation like @RequestMapping(method = RequestMethod.GET, path = “/helloWorld”
  • there is a short version: @GetMapping(path = x)
  • To return an object(bean) in api response, the class must have getter for its property
  • dispatcher servlet find the right controller to execute a request
  • ResponseEntity response a status code (Step10)
  • throw a exception with annotation to reurn error status like 404
  • create a class extends from ResponseEntityExceptionHandler to make all controller return standard error response (Step12)

Validation

  • check input is correct when calling api
  • add annotation like @Size @Past
  • In order to give api consumer useful message with validation fail, override the method handleMethodArgumentNotValid from ResponseEntityExceptionHandler (step15)

HATEOAS (Hypermedia as the Engine of Application State)

  • make the api return data as well as return different actions we can perform on the data
  • client make a request, and the next steps are handed to them in the response
  • provides additional links to the request along with the response
  • hard to maintain a list of links if we manually hard code them
  • return EntityModel of <data> (step 15 5:25)

Internationalization (i18)

  • customize language base on country
  • during request, api cosumer can specify the language in header
  • Accept-Language: fr
  • add a new paramter call “locale” in controller method
  • to avoid passing in locale in all parameter, we can read locale directly in LocaleContextHolder
  • pick value in property files instead of hard coding response
  • use messageSource to return value from property file

Content Negotiation

  • specify return xml or json response
  • api consumer speciy in header
  • Accept: Application/xml
  • automatically handle by spring boot when adding dependency com.fasterxml.jackson.dataformat

Swagger

  • documentation that is automatically generated from code, to avoid maintance
  • add dependency springdoc-openapi-ui
  • type localhost:8080/swagger-ui.html

Actuator

  • use for monitoring purpose, expose a bunch of url
  • implement services that return response to these url

HAL Explorer

  • provide a UI to navigate through the HATEOS and actuator links

Filtering

  • When return a object from Get Request, we can filter some fields using @JsonIgnore on the field or on the class
  • For dynamic filtering(filter different combinations of fields in different request), we can define MappingJacksonValue mapping
  • step 25 (4:01)

Versioning

  • Create two versions of the same service — step 27 (1:30)
  • a basic way is to having different url for the request, call uri versioning
  • another way is let client pass in a parameter, call request parameter versioning
  • can use header parameter as well, call header versioning
  • use the produces paramter (5:04). call accept header versioning / mime type versioning
  • header versioning are harder to document because they are not automatically generted by swagger

Authentication

  • Spring boot provided a basic security dependency
  • When using it, change authenticaion to basic authentication and pass in the password copied from log
  • change to custom password in local.properties

Richardson Maturity Model

  • how restful is your service
  • level 0: Expose SOAP web services in rest style
  • level 1: Expose resources with proper URI
  • level 2: level 1 + http protocal
  • level 3: level 2 + HATEOAS

Web Service Best Practice

  • Consumer first (documente help)
  • make best use of http
  • use http response code status
  • No secure Info in URL
  • Use Plurals
  • Use nouns for resources (For exceptions, define a consistent approach)

Microservices

  • Style to developmening a single application as a suite of small services
  • These services are independently deployable
  • REST
  • Small well chosen deployable unit
  • cloud enabled (have multiple deployed instance of the same service)

Advantage

  • Adapte new technology and process easily
  • Each microservices can be built with different technoloy
  • Dynamic Scaling
  • Faster release cycles
  • because we are developing smaller component

Challenge

  • Bounded Context
  • How to identity the boundary for each micro services?
  • it is an evolutionary process base on the knowledge we have at that time
  • Configuration managment
  • multiple instance & enviornment
  • Dynamic scale up and down
  • Visibility
  • How to locate bug when you have so many micro services
  • Pack of cards
  • If one microservice go down, all the other micro services that depend on it also go down

Spring Cloud

  • Spring cloud provides solution to the challenges above
  • Configuration managment
  • Spring Cloud Config Server
  • Store all configuration in a git repo and SpringCloudConfigServer will expose the config to the services
  • Dynamic scale up and down
  • Ribbon Load Balancing
  • distrubte load among all services
  • Naming Server has 2 important feature
  • all microservices register with the naming server
  • provide url of the available instance of services for service
  • Visibility and monitoring
  • Ziplin Distributed Tracing
  • trace a request across multiple components
  • Netflix API Gateway
  • Don’t have to implement basic features like logging in every microservice
  • Fault tolerance (Pack of cards)
  • Hystrix
  • Configure a default response when a service is down

Microservices with spring cloud

  • Give your microservice a good name in local.properties
  • spring.application.name=””
  • server.port=8888

Pick up value from application.properties

  • Create a configuration class with @ConfigurationProperties

Spring Cloud Config Server

Setting up Dynamic Port in the Response

  • We can run multiple instances of the same microservices by specifying the port number in IDE’s Run Configurations
  • (Step 12 4:16) Go to VM arguments -Dserver.port=8001., will override what is in application.properties
  • There is a class call Enviornment that we can get the port and pass back in response if needed

Feign

  • To call one microservice from another microservice
  • Without Feign: return a RestTemplate with the other service’s url (step 17 4:59)
  • (step 18) Create a Proxy interface and just call the method of that proxy in controller

Eureka Naming Server (Service Registery)

  • For different instances of the microservices, we don’t want to hard code the url:port because they might went down
  • This naming server itself is another microservices (Step 19)
  • Don’t register Eureka with itself (setting in local.properties)
  • Once up we can launch UI in localhost:{port} and see what is registered with Eureka
  • For a microservices to register with Eureka: import start-netflix-eureka-client
  • “Add the dependency is all you need to connect with Eureka”

Load Balancing

  • In the Feign proxy interface, if we do not specify a url:
  • Feign will talk to Eureka and pick up the instances of service and do load balancing automatically (step 22 -148)
  • spring cloud starter load balancer is a dependency imported from eureka dependency

Spring cloud API Gateway

  • An application could have hundreds of microservices and they have similiar features like authentication, authorization, logging, rate limiting, monitoring
  • API gateway is solution and Spring cloud gateway is recommended dependency
  • It is its own microservice with eureka and gateway dependency (step 22–149)
  • you can implement all the common features in API gateway and the API gateway would take care of the common features and invoke the intented microservice (step23)
  • “entry point” to your backend
  • Custom Routes
  • Create configuration class to redirect incoming request to url
  • to find url from naming server use lib:// (step 24 9:00)
  • You can match request by url or base on query, etc
  • Logging Filter
  • You can have a separate class only to filter all request and log them out (step 25)

Resilience4j (Circuit Breaker)

  • When one microservice depend on another like a chain, if one of them in the middle is down or slow it will affect others depend on it
  • It is its own microservice
  • If one microservice is having problem, instead of keep hitting it with request, return some default result back
  • retry
  • Have a retry annotation default retry 3 times if any exception happen, if 3 times all failed only then it will return an error back
  • To control retry behavior, configure setting in local.properteis (step 27 5:25)
  • allow waiting time between retry and exponential waiting
  • retry annotation also take in a fallback method
  • circuit breaker
  • Have a circuit breaker annotation (step 28)
  • if a response is failing repeatedly, it return a default respond instead of calling the dependency
  • a circuit breaker can be a 3 states, close, open, half open
  • close state (no problem, always be calling the dependency)
  • open state(service down, directly return default)
  • half open(send a percentage of request)
  • to move from open to half open, there is a wait duration setting
  • if half open request success go back to close state, other wise go to open state
  • Rate limiting
  • there is a rate limiting annotation
  • configure the limit in local.properties (step 29 2:10)
  • the request over the rate limit will get an error
  • BulkHead
  • how many concurrent calls are allow
  • there is a bulkhead annotation
  • change the concurrent call number in local.properteis (step 29 4:52)

--

--

Yat Man, Wong
Yat Man, Wong

Written by Yat Man, Wong

Android developer, problem solver, real man in training

No responses yet