10 Microservices
10 Microservices
STUDY GUIDE
Module 1
Introduction to MicroServices
Author
Som Prakash Rai
A layer can only call into layers that sit next to it. It can be hard to introduce
changes in one part of the application without touching the rest of the
application. That makes complex for frequent updates and limiting how
quickly new features can be added.
In the early stages of the project it works well and basically most of the big
and successful applications which exist today were started as a monolith.
Prefer for Traditional business domains which has low Frequency of updates
2) Overloaded IDE, Large code base makes IDE slow, build time increase.
3) Deployment challenges.
Any change in the any one module would require the entire application to be
deployed again.
Continuous deployment is difficult.
You must redeploy the entire application on each update.
5) Big database.
6) Fault Tolerance.
If a specific feature is not working it will make the system goes down. In
order to handle this problem, the system has to be rebuilt, retested and
redeployed
Bug in any module (e.g. memory leak) can potentially bring down the entire
process. Moreover, since all instances of the application are identical, that
bug will impact the availability of the entire application.
5) Services are responsible for persisting their own data or external state. This
differs from the traditional model, where a separate data layer handles data
persistence.
a) Microservices benefits
6) Selective scaling
A monolithic application, packaged as a single WAR or an EAR, can only be
scaled as a whole. In Microservices, each service could be independently scaled
up or down depending on scalability requirement. As scalability can be
selectively applied at each service, the cost of scaling is comparatively less with
the microservices approach.
7) Fault isolation:
If an individual microservice becomes unavailable, it won't disrupt the entire
application, as long as any upstream microservices are designed to handle faults
correctly.
8) Data isolation:
It is much easier to perform schema updates, because only a single
microservice is affected. In a monolithic application, schema updates can
become very challenging, because different parts of the application may all
touch the same data, making any alterations to the schema risky.
9) Allowing substitution
Microservices are self-contained, independent deployment modules enabling
the substitution of one microservice with another similar microservice. Many
large enterprises follow buy-versus-build policies to implement software
systems. A common scenario is to build most of the functions in house and buy
certain niche capabilities from specialists outside.
1) Complexity:
A microservices application has more moving parts than the equivalent
monolithic application. Each service is simpler, but the entire system as a
whole is more complex.
3) Lack of governance:
The decentralized approach to building microservices has advantages, but
it can also lead to problems. You may end up with so many different
languages and frameworks that the application becomes hard to maintain.
It may be useful to put some project-wide standards in place, without
overly restricting teams' flexibility. This especially applies to cross-cutting
functionality such as logging.
6) Management:
To be successful with microservices requires a mature DevOps culture.
Correlated logging across services can be challenging. Typically, logging
must correlate multiple service calls for a single user operation.
7) Skillset:
Microservices are highly distributed systems. Carefully evaluate whether
the team has the skills and experience to be successful.
3) Messaging (JMS / AMQP), HTTP, and REST are commonly used for
interaction means communication between microservices.
SYNchronous Communication
o In synchronous communication, the http listener such as tomcat or
jetty or jboss, etc is needed but not messaging listener. When a caller
requests a service, it passes the required information and waits for a
response.
Advantages:
1) No messaging server overhead.
2) The error will be propagated back to the caller immediately.
Disadvantages:
1) The caller has to wait until the request has been processed.
2)Adds hard dependencies (tight coupling) between Microservices i.e., if
one service in the chain fails, then the entire service chain will fail.
ASYNchronous Communication
o The asynchronous style is based on reactive event loop semantics
which decouple microservices.
Advantages:
1) Decouple Microservices
2) Higher level of scalability because services are independent. Hence if
there is a slowdown in one of the services, it will not impact the entire
chain.
Disadvantages:
1) It has a dependency to an external messaging listener.
2) It is complex to handle the fault tolerance of a messaging listener.
Shared data models, Shared schema, and shared tables are disasters when
developing microservices.
If the services have only a few tables, it may not be worth investing a full
instance of a database like MySQL instance. In such cases, schema level
segregation is good enough to start with.
h) Shared Libraries
Sometimes code and libraries may be duplicated in order to adhere to
autonomous and self-contained principle.
1) Netflix
Netflix, an international on-demand media streaming company, is a pioneer
in the microservices space.
Netflix transformed their large pool of developers developing traditional
monolithic code to smaller development teams producing microservices. At
Netflix, engineers started with monolithic, went through the pain, and then
broke the application into smaller units that are loosely coupled and aligned to
the business capability.
3) Twitter
When Twitter experienced growth in its user base, they went through an
architecture-refactoring cycle. With this refactoring, Twitter moved away from a
typical web application to an API-based event driven code. Twitter uses Scala
and Java to develop microservices with polyglot persistence.
4) Uber
When Uber expanded their business from one city to multiple cities, the
challenges started. Uber then moved to microservice based architecture by
breaking the system into smaller independent units. Each module was given to
different teams and empowered them to choose their language, framework, and
database. Uber has many microservices deployed in their ecosystem using REST.
5) eBay :
In 2011, when eBay was introducing microservices, the company had 97
million active users and 62 billion gross merchandise volume. On a typical day,
eBay IT systems had to deal with massive traffic, like 75 billion database calls, 4
billion page views and 250 billion search queries. The change to microservice
architecture wasn’t the first major switch of technology at eBay; the company
faced similar transitions in 1999 and 2005.
Spring boot is a tool to develop such kinds of services i.e., Spring Boot
enables microservices development by packaging all the required runtime
dependencies in a executable fat jar file.
Software Required
1. JDK 1.8
2. Spring Tool Suite
3. Maven 3.x /Gradle
4. Spring Framework 5.x RELEASE
5. Spring Boot 2.x RELEASE
6. RabbitMQ / Kafka
7. Git
8. Spring Cloud
9. MySQL DB
Som
JTC
Prakash
Som
JTC
Prakash
Som
JTC
Prakash
JTCBookStore
SomPrakash
JTC
Som
JTC
Prakash
Som
JTC
Prakash
JTCBookStore
JTCBookStore
create table
mybooks( book_id int
primary key, book_name
char(30), author char(15),
publications char(15),
category char(15)
);
create table
mybookratings( book_id int
primary key, avg_rating double,
number_of_searches int
);
create table
mybookinventory( book_id int
primary key, books_available int
);
a) pom.xml
b) application.properties
c) jtcBookPriceConfig.java
d) BookPriceApplication.java
7) Update pom.xml
8) Update application.properties
spring.application.name=MyBookSearchMS
server.port=8000
spring.datasource.url=jdbc:mysql://localhost:3306/jtcbooksdb
*** Book.java
*** BookRating.java
*** BookInventory.java
http://localhost:8000/swagger-ui.html
GET :
http://localhost:8000/mybooks/Somprakash/Spring
GET : http://localhost:8000/mybook/101
PUT : http://localhost:8000/updateBookRating
PUT : http://localhost:8000/updateBookInventory
http://localhost:8000/mybooks/Somprakash/Web
http://localhost:8000/mybooks/Somprakash/Spring
http://localhost:8000/mybook/101
http://localhost:8000/mybook/102
1. BookController.java
package com.jtcindia.booksearch;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.ApiOperation;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@CrossOrigin
@RestController
public class BookController {
@Autowired
BookService bookService;
@GetMapping("/mybooks/{author}/{category}")
@ApiOperation(value = " getBooks", response = List.class, notes = "Returns List of
Books for given Author and Category")
public List<Book> getBooks(@PathVariable String author, @PathVariable String category)
{ log.info("---BookController---getBooks()----");
System.out.println(author + "\t" + category);
return bookService.getBookInfo(bookId);
}
@PutMapping("/updateBookRating")
@ApiOperation(value = " updateBookRating", response = void.class, notes =
"updateBookRating")
public void updateBookRating(@RequestBody BookRating bookRating)
{ System.out.println("-------BookController-----updateBookRating()---- ");
bookService.updateBookRating(bookRating);
}
@PutMapping("/updateBookInventory")
@ApiOperation(value = " updateBookInventory", response = void.class, notes =
"updateBookInventory")
public void updateBookInventory(@RequestBody BookInventory bookInventory)
{ System.out.println("-------BookController-----updateBookInventory()---- ");
bookService.updateBookInventory(bookInventory);
}
}
2. BookPriceInfo.java
package com.jtcindia.booksearch;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
public class BookPriceInfo
{ private Integer bookId;
private double price;
private double offer;
//Constructors
//Setters and Getters
//toString()
}
//Constructors
//Setters and Getters
//toString()
}
4. BookService.java
package com.jtcindia.booksearch;
import java.util.List;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
public interface BookService {
public List<Book> getBooks(String author,String category);
public BookInfo getBookInfo(Integer bookId);
public void updateBookRating(BookRating bookRating);
public void updateBookInventory(BookInventory bookInventory);
}
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@Service
@Transactional
public class BookServiceImpl implements BookService{
@Autowired
BookInventoryDAO bookInventoryDAO;
@Autowired
BookRatingDAO bookRatingDAO;
@Autowired
BookDAO bookDAO;
@Override
public List<Book> getBooks(String author, String category)
{ List<Book> mybooks=new ArrayList<>();
bookInfo.setAvgRating(bookRating.getAvgRating());//6
bookInfo.setNumberOfSearches(bookRating.getNumberOfSearches());//7
return bookInfo;
}
@Override
public void updateBookRating(BookRating bookRating)
{ bookRatingDAO.save(bookRating);
}
@Override
public void updateBookInventory(BookInventory bookInventory)
{ bookInventoryDAO.save(bookInventory);
}
}
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@Repository
public interface BookDAO extends JpaRepository<Book,Integer> {
public List<Book> getBooksByAuthorAndCategory(String author,String category);
public List<Book> getBooksByAuthor(String author);
public List<Book> getBooksByCategory(String category);
}
7. BookRatingDAO.java
package com.jtcindia.booksearch;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@Repository
public interface BookRatingDAO extends JpaRepository<BookRating,Integer> {
}
8. BookInventoryDAO.java
package com.jtcindia.booksearch;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@Repository
public interface BookInventoryDAO extends JpaRepository<BookInventory,Integer> {
}
import javax.persistence.*;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@Entity
@Table(name="mybooks",schema = "jtcbooksdb")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="book_id")
private Integer bookId;
@Column(name="book_name")
private String bookName;
@Column(name="author")
private String author;
@Column(name="publications")
private String publications;
@Column(name="category")
private String category;
//Constructors
//Setters and Getters
//toString()
}
10. BookRating.java
package com.jtcindia.booksearch;
import javax.persistence.*;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@Id
@Column(name="book_id")
private Integer bookId;
@Column(name="avg_rating")
private double avgRating;
@Column(name="number_of_searches")
private int numberOfSearches;
//Constructors
//Setters and Getters
}
11. BookInventory.java
package com.jtcindia.booksearch;
import javax.persistence.*;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@Entity
@Table(name="mybookinventory",schema = "jtcbooksdb")
public class BookInventory {
@Id
@Column(name="book_id")
private Integer bookId;
@Column(name="books_available")
private int booksAvailable;
//Constructors
//Setters and Getters
}
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.google.common.base.Predicates;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@SpringBootApplication
public class jtcBookSearchConfig implements WebMvcConfigurer {
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/*
* @Author : Somprakash Rai
* @company : JtcIndia
* */
@SpringBootApplication
@EnableSwagger2
public class BookSearchApplication {
static Logger log = LoggerFactory.getLogger(BookSearchApplication.class);
server.port=8000
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jtcbooksdb
spring.datasource.username=root
spring.datasource.password=Somprakash
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
logging.level.root=INFO
logging.pattern.console=%-5level %logger{36} - %msg%n
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
</dependencies>
<build>
<finalName>MyBookSearchMS</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
MyBookSearchMS http://localhost:8000/mybook/{bookId}
MyBookSearchMS http://localhost:8000/updateBookRating
MyBookSearchMS http://localhost:8000/updateBookInventory