Getting Started
Microservices are an architectural style where a single application is built as a suite of small services each running as independent processes and intercommunicating via open protocols .It deals with building independent applications as a suite of smaller services ,each of which run as an independent process. Microservices communicate with each other using open protocols like HTTP .These services are separately deployed and maintained and encapsulate business functionality .Services are independently replaceable .They are not same as SOA –its about decomposing single application .Organizations are moving fast onto microservices like Netflix has done a great deal of work to eliminate the Java Monolithic architecture . Monolithic versus Microservices
Lets take an example of a traditional monolithic shopping cart application to understand microservices better.
Fig 4.1 Monolithic Architecture
The issue here is earlier we used to support only web interfaces as the client interfaces but now we have proliferation of client technologies .The figure below depicts the scene .The controllers which were designed for the web interfaces were not designed for these other channels. There are also a lot of superior and numerous backend technologies .Monolithic code base is also tough to be managed by larger and bigger teams working in parallel. Microservices allow the team to work on separate business functionalities (cross functional teams ) .We are also stuck in monolithic applications in case we want to use better technologies for some pieces of the functionalities .
Fig. 4.2 Varied UI Interfaces in modern day applications The advantages and disadvantages of monolithic are stated under :
Advantages :
Drawbacks:
The same Shopping cart architecture using microservices could be portrayed as below (using polyglot persistence) :
Fig. 4.3 Scenario Depicting MicroServices
Microservices should have very clear interfaces as part of the API gateway .Netflix cloud native architecture is a very good example of Microservices .Microservices should not be orchestrated but choreographed. (decentralized governance ).We can break a monolithic into a microservices using a single responsibility principal of bounded context besides splitting into Noun / verb based functionality Microservices are smart but
their communication should be dump. Thus the advantages of microserivces are as follows:
Advantages:
Disadvantages :
Spring Boot
It is a technology to started getting started with Spring quickly
.(http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/) Spring Boot provides intelligent defaults for configuration .It is not about code
generation .It gives Easier dependency management .Its about automatic configuration and provides different build options .We can go to start.spring.io to download the Spring Initializer and can be used in any IDE.The following demonstrate the set up screen .
The spring boot starter will resolve all the transitive dependencies
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
Other important plugins it will bring along are as follows :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
- <plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
- <dependencies>
- <dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
</dependencies>
</plugin>
MicroServicesBootApplication Java class is the default java class .We can run the class as described in the screenshot below .The following operations are accomplished as part of the application execution
We can add the dependency Spring-boot-starter-web in pom to turn it to a web application and run it as a Java application .The test controller we may write looks like below :
package demo.controller;
import org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hi")
public @ResponseBody String hi() { return "hello";
} }
It will respond back to localhost:8080/hi with hello .The following actions are taken here : (Spring Boot will launch Tomcat on its own )
We can turn this into a war file using the SpringBootServletInitializer in the application class and the setting in pom to war .
Spring Boot also supports JSP and templates like Freemarker , Thymeleaf .For Tymeleaf , we will add the following dependency .Please keep the template under the templates folder .
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
The controller can be changed as follows :
@Controller
public class HelloController {
@RequestMapping("/hi/{name}")
public String hi(Map model, @PathVariable String name) {
model.put("name",name);
return "hello";
} }
The template can be changed as follows :
For using Rest capabilities we make use of domain values as return values /parameters .We can mark with annotations
@RequestBody and @ResonseBody .Spring automatically handles xml and JSON conversions .We create domain objects Team and Player as follows :
package demo.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Player {
@Id
@GeneratedValue Long id;
String name;
String position;
public Player() { super();
}
public Player(String name, String position) { this();
this.position = position;
this.name = name;
}
public Long getId() { return id;
}
public void setId(Long id) { this.id = id;
}
public String getName() { return name;
}
public void setName(String name) { this.name = name;
}
public String getPosition() { return position;
}
public void setPosition(String position) { this.position = position;
} }
package demo.domain;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity
public class Team {
@Id
@GeneratedValue Long id;
String name;
String location;
String mascotte;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="teamId") Set<Player> players;
public Team() { super();
}
public Team(String location, String name, Set<Player>
players) {
this();
this.name = name;
this.location = location;
this.players = players;
}
public Long getId() { return id;
}
public void setId(Long id) { this.id = id;
}
public String getName() { return name;
}
public void setName(String name) { this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) { this.location = location;
}
public String getMascotte() { return mascotte;
}
public void setMascotte(String mascotte) { this.mascotte = mascotte;
}
public Set<Player> getPlayers() { return players;
}
public void setPlayers(Set<Player> players) { this.players = players;
} }
We will change the controller as follows : package demo.controller;
import org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
@RRestController
public class HelloController { private Team team;
public void init(){
Set<Player> players = new HashSet();
players.add (new Player ("Charlie Brown","pitcher" ));
players .add (new Player ("Snoopy","shortstop"));
team = new Team ("California","Peanuts",players);
}
@RequestMapping("/hi") public Team hi() { return team;
} }
The browser will return us a json response as follows :
In case we need the response in XML , annotate the domain class with JAXB .Next we will add some JPA capability by adding the spring-boot-starter-data-jpa ( <artifactId>spring-boot-starter-data-jpa</artifactId>) which adds Spring Transaction management, adds Spring ORM, adds Hibernate /Entity manager and Spring Data JPA .It will not bring Data base driver .For the DAO layer, we can provide the interface and Spring Data will implement it for us .
We should add the JPA annotations to the domain objects .(already included in the above code for domain classes ) We need to add the following dependency in the pom for hsql DB
<groupId>org.hsqldb</groupId>
<artifactId>hsql-db</artifactId>
We need to create the repository objects for Team and Player as follows : Crud Repository is from Spring data repository package .
package demo.repository;
import org.springframework.data.repository.CrudRepository;
import
org.springframework.data.rest.core.annotation.RestResource;
import demo.domain.Team;
@RestResource(path="teams", rel="team")
public interface TeamRepository extends CrudRepository<Team,Long>{
}
Spring data JPA is intelligent enough to implement the following method defined by us in the CRUD Repository Objects .
In the application class ,we can declare the Crud repository for Team and Player and we can Autowire them as follows .
The controller code can be written to fetch the Team based on the id or name .
package demo.controller;
import
org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RestController;
import demo.domain.Team;
import demo.repository.TeamRepository;
@RestController
public class TeamController {
@Autowired TeamRepository teamRepository;
@RequestMapping("/teams") public Iterable<Team> getTeams() {
return teamRepository.findAll();
}
@RequestMapping("/teams/{id}")
public Team getTeam(@PathVariable Long id){
return teamRepository.findOne(id);
} }
The response will be return the json response as follows :
Last concept is of Spring Data REST which plugs into dynamic repositories ,generates RESTful interface and thus we need the code to override the defaults only .The flow is depicted below .
Fig 4.4 Architecture following MicroServices Here we will add the dependency as :
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
We add a RestResource to the DAO as follows:
The json response is going to return us the entire team as follows
Thus when the applications starts the RestResource annotations are interpreted and Spring Data creates the Controllers and Request Mappings .In case we provide the crud repository for Players , the output will return us the links for payers as follows :
package demo.repository;
import org.springframework.data.repository.CrudRepository;
import
org.springframework.data.rest.core.annotation.RestResource;
import demo.domain.Player;
@RestResource(path="players", rel="player")
public interface PlayerRepository extends CrudRepository<Player,Long>{
}
Spring Cloud
There are a lot of sub-projects under the Spring Umbrella which emerged since 2006 as shown below. Spring cloud is a sub-project under the Spring IO umbrella .
Fig 4.4 Spring Cloud Umbrella
Spring Cloud provides libraries to apply common patterns needed in distributed applications such as centralized configuration management ,service Registration ,Load Balancing,Service –to-service calls Circuit breakers ,Routing,
Etc,Netflix became the trailblazers in cloud computing and choose to publish many general use technologies as open source projects .Spring team realized that Netflix has addressed quite a few key architectural items in the cloud environment .Spring team realized the work already done by the Netflix team easily consumable .Spring cloud project are based on Spring Boot .We need to use the spring-cloud-starter-parent and spring-cloud – starter- … dependencies .
Spring Cloud Config
This is the centralized version management for distributed/cloud based applications .Applications have connections to resources , message servers ,other applications ,etc.Usually they use external configuration to adjust the software behavior and its not hard coded .The different configuration options are depicted as follows:
With microservices , we have large number of dependent services ,hence greater need for configuration .Manual configuration will be brittle. Environment variables change
needs deployment. Also, we need to have traeability with respect to version control. The desired solution for configuration management can be mentioned as below
The advantages of the config are depicted below:
Spring Cloud config is a designated centralized server to serve up configuration information. It is backed by some kind of source control .Client connect over HTTP and retrieve their configuration settlings .Spring Cloud server config uses an environment repository .The configuration file naming convention is
<spring-application-name>-<profile>.yml. Spring application name is set up by the bootstrap.yml.Profile can be set to work in different mode .
Fig 4.5 Spring Config
Spring cloud config server code is available at Github or we can build our own following the below steps .
1. Include following dependencies in pom <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.SR5</version>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
2. Modify the application.yml file with the location of configuration repository.
spring:
cloud:
config:
server:
git:
uri: https://github.com/malidee/Microservices-With-Spring-Student-Files
searchPaths: ConfigData
# "native" is used when the native profile is active, for local tests with a classpath repo:
native:
searchLocations: classpath:offline-repository/
server:
port: 8001
3. In the application class just add the @EnableConfigServer annotation .
On the client Side, following steps should be followed : 1. User Spring cloud starter Parent as a Parent pom.
2. Include the Spring cloud starter for config.
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
3. Configure Application name and server location in bootstrap.yml
--- spring:
profiles:
active: northamerica application:
name: lab-3-client cloud:
config:
uri: http://localhost:8001 server:
port: 8002
Service Discovery with Spring Cloud Eureka
Service discovery means that the client has discovered the other clients though registering .When we use microservices ,there is a huge number of inter service calls.Service discovery provides a single lookup service .Possible solutions in the space are Eureka ,Zookeeper ,etc .Eureka comes from Netflix .Eureka provides a lookup server .Client services register with Eureka.by providing meta data on host ,port,health indicatorURL ,etc. and sends heatbeats to Eureka .By enabling the @EnableEurekaServer on the spring boot application configuration class , we can make a eureka server (as follows) .Generally multiple eureka servers run simultaneously and they share a state with each other .
The common server configuration are shown below :
For the eureka client ,add the following depednecy
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
The application configuration class will need an annotation
@EnableDiscoveryClient
Finally, set the client service url in the application .properties file.
eureka:
client:
serviceUrl:
defaultZone:
http://localhost:8010/eureka/,http://localhost:8011/eureka/,http:/
/localhost:8012/eureka/,http://localhost:8013/eureka/
Eureka server is designed for multi –instance use. Many run in different availability zones. It does not persist service registrations and relies on client registrations .
Spring Cloud Ribbon
Load balancer is a component that sits in front of an application (web server) and its purpose is to distribute the load or the incoming traffic among several servers.A client side load balancer is part of the client application software and its purpose is to select which server to call .
Fig 4.6 Spring Cloud Ribbon
This kind of resilience and adaptability is often needed in a microservice .The client side load balancer might decide based on factors such as fast response from a server in a particular zone .But in case the server in that region is down the client side load balancer can route the call to other regions .Ribbon is another project which is part of the Netflix OSS family .It automatically integrates with Eureka.It has buid in failure resiliency (Hystrix).Spring cloud provides an easy API wrapper for using Ribbon.It has provision for caching and batching and it support multiple protocols .Ribbon discovers what the list of possible servers are .Server lists can be static or dynamic .An example of static list is shown below :
Spring cloud refers to servers in the same zone as the Filtered list of servers .The Ribbon client pings the server in order to check the health of the server .This is performed by Eureka in Spring Cloud .In Spring Cloud default load balancer is called as ZoneAwareLoadBalancer.Rule is the single module of intelligence that makes the decisions on whether to call or not .The steps for using a Spring Cloud are as follows :
1. Use the Spring Cloud Starrter parent as a Parent pom.
2. Include the ribbon dependency
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
3. We can then use the Ribbon code in the following manner
Declarative REST Clients using Feign
Feign is a declarative REST Cleint .It is part of the Netflix OSS.It allows to write calls to REST services with no implementation code. Spring cloud provides easy wrapper for using Feign .Feing is an alternative to technology like Spring REST template .We need to define interfaces for the Java Rest client code.Within them, define the method signatures that we want to make .Then annotate interfaces with Feign annotation and annotate the individual methods with the Spring MVC .During Runtime Feign will automatically implements the code to call REST services and processes the response. Below shows an implementation example.
In the Spring configuration classes ,we need to put an annotation @EnableFeignClients so that during the application start Feing libraries can provide a runtime implementation of whatever we have configured.The below diagram illustrates this .Feign integrates very well with Ribbon and Eureka.
Fig 4.7 @EnableFeignClients usage at Startup Spring Cloud Hystrix – Circuit Breaker
Whenever we have large number of interacting services ,there is always a possibility that one of them could be in a failed state .This will effect other clients and the result of this will be a ripple effect leading to a visible problem called as cascade failures .(as shown below)
Fig 4.8 Spring Cloud Hystrix
Microservices are very vulnerable to these type of cascade failures .Thus we have to take out and isolate the failures of individual services to avoid cascade failures .This leads us to the cirduite breaker pattern to avoid cascade failures .Hystrix is a software circuit breaker which is part of the Netflix OSS.Its a light weight easy to use wrapper provided by Spring Cloud .It detects the failures and opens to disallow further calls .It identifies ‗fallback‘ – what to do in case of a service dependency failure .It automatically closes itself after the interval .It is said to be closed when operating normally and open when failure is detected .In order to use Hystrix , we need to add a dependency and enable Hystrix within a configuration class .(as follows)
Below is an example of the Hystrix use :
We can fine tune the failure detection and recovery mode as follows:
Hystrix provides a dashboard to check the status of the circuit breakers (as shown below ).In order to enable the dashboard we need to add the annotation @EnableHystrixDashboard in the configuration class and add the dependencies spring-cloud-started-hystrix-dashboard and spring-boot-starter-actuator
CHAPTER 5 - BIG DATA TECHNOLOGY (HADOOP)