Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

MicroServices on the Move

Introduction

Why Microservice?

Microservices are an approach to developing a single application as a set of lightweight, independent collaborating services. The main benefit of using microservices is that, unlike a monolithic architecture style, a change made to a small part of the application does not require the entire structure to be rebuilt and redeployed.

Microservices have many coordinating moving parts. While the tools are getting better, it is still a highly complex architecture with lots of moving parts.

Applications grow more complex over time, and that complexity creates challenges in development. There are two essential strategies to manage this problem: a team can keep everything together (create a monolith) or a team can divide a project into smaller pieces (create microservices).

Microservices, on the other hand, describe a strategy for decomposing a large project into smaller, more manageable pieces.

A microservice is a piece of application functionality factored out into its own code base, speaking to other microservices over a standard protocol.

Microservices can be distributed globally for low latency and can even run multiple versions of the same service simultaneously for redundancy.

Monolithic app is One Big Program with many responsibilities; microservice-based apps are composed of several small programs, each with a single responsibility.

Use Case

Prerequisites

To accomplish this, first divide your business requirements into related groups like Store management logic, Product logic, Company logic and a web user interface. Write a program to provide each service and connect each service to a language-agnostic protocol like HTTP, AMQP, or Redis. Finally, pass messages via the protocol to exchange data with other services.

What we need to do

Create three Maven projects in this hands-on, each of them will symbolize back-end functionality, i.e. reusable APIs, and one of them held a composition, that is, will be a consumer of the other.

To begin, let’s create 3 simple Maven projects, Customer-backend, Bank-backend, HealthCare-backend and Retail-backend.

In the poms of the 3 projects, we will add the dependencies for the creation of our REST services and startup Spring Boot

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.0.RELEASE</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-jersey</artifactId>
</dependency>
</dependencies>

The first class that we create named as MicroservicesApp, will be identical in all three projects, because it only works as an initiator to Spring Boot – as defined by @SpringBootApplication annotation – rising a Spring context and the embedded server.

@SpringBootApplication
public class MicroservicesApp {
  public static void main(String[] args) {
   SpringApplication.run(MicroservicesApp.class, args);
  }
}

The next class we will see is the MicroservicesAppConfig. In this class, which uses the @Configuration Spring annotation to indicate to the framework that it is a resource configuration class, we set the Jersey, which is our ResourceManager responsible for exposing REST services for the consumers.

Note: In a real application, this class would also create data sources for access to databases and other resources, hence we will use mocks to represent the data access.

We will also instantiate a RestTemplate. RestTemplate is a standardized and very simple interface that facilitates the consumption of REST services.  This class is one of the new features in the Spring Framework.

@Configuration
public class MicroservicesAppConfig {
@Named
	static class JerseyConfig extends ResourceConfig {
		public JerseyConfig() {
		  this.packages(com.microservices.poc.rest");
		  }
	}
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();

return restTemplate;
}
}

We create a class of DTO and a REST service, the class which is a simple POJO:

public class Store {

	private long storeId;
	private String storeName;
	private String storeLoc;
	public long getStoreId() {
		return storeId;
	}
	public void setStoreId(long storeId) {
		this.storeId = storeId;
	}
	public String getStoreName() {
		return storeName;
	}
	public void setStoreName(String storeName) {
		this.storeName = storeName;
	}
	public String getStoreLoc() {
		return storeLoc;
	}
	public void setStoreLoc(String storeLoc) {
		this.storeLoc = storeLoc;
	}

The REST service, in turn, has only 2 capabilities, a search for all Banks and a Bank Detail query from the given ifsc_code:

@Named
@Path("/")
public class StoreRest {

	private static List<Store> store = new ArrayList<Store>();

	static {

		Store store1 = new Store();
		store1.setStoreId(101);
		store1.setStoreName("Store 1");
		store1.setStoreLoc("Location 1");

		Store store2 = new Store();
		store2.setStoreId(102);
		store2.setStoreName("Store 2");
		store2.setStoreLoc("Location 2");

		Store store3 = new Store();
		store3.setStoreId(103);
		store3.setStoreName("Store 3");
		store3.setStoreLoc("Location 3");

		Store store4 = new Store();
		store4.setStoreId(104);
		store4.setStoreName("Store 4");
		store4.setStoreLoc("Location 4");

		Store store5 = new Store();
		store5.setStoreId(105);
		store5.setStoreName("Store 5");
		store5.setStoreLoc("Location 5");

		store.add(store1);
		store.add(store2);
		store.add(store3);
		store.add(store4);
		store.add(store5);

	}

	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public List<Store> getStores() {
		return store;
	}

	@GET
	@Path("store")
	@Produces(MediaType.APPLICATION_JSON)
	public Store getStore(@QueryParam("storeId") long storeId) {

		Store st = null;

		for (Store s : store) {

			if (s.getStoreId() == storeId)
				st = s;

		}

		return st;
	}

}

This concludes our REST Store service.

For products, we have methods to search all products or a single product through one of its ids and finally we have the company service, which through a submitCompany method gets the data of a product and a store – whose keys are passed as parameters to the method and returns a company header. The classes that make up our services are the following:

public class Product {

	private long productId;
	private String productName;
	private String productDesc;

	public long getProductId() {
		return productId;
	}

	public void setProductId(long productId) {
		this.productId = productId;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public String getProductDesc() {
		return productDesc;
	}

	public void setProductDesc(String productDesc) {
		this.productDesc = productDesc;
	}

}

public class Product {

	private long productId;
	private String productName;
	private String productDesc;

	public long getProductId() {
		return productId;
	}

	public void setProductId(long productId) {
		this.productId = productId;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public String getProductDesc() {
		return productDesc;
	}

	public void setProductDesc(String productDesc) {
		this.productDesc = productDesc;
	}

}

Finally, the classes that make up our above mentioned company service in the Company-backend project is:

public class Company {

	private long companyId;
	private String companyName;
	private String companyLoc;
	private Store store;
	private Product product;
	private long stock;
	private Date stockDate;

	public long getStock() {
		return stock;
	}

	public void setStock(long stock) {
		this.stock = stock;
	}

	public Date getStockDate() {
		return stockDate;
	}

	public void setStockDate(Date stockDate) {
		this.stockDate = stockDate;
	}

	public Store getStore() {
		return store;
	}

	public void setStore(Store store) {
		this.store = store;
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public long getCompanyId() {
		return companyId;
	}

	public void setCompanyId(long companyId) {
		this.companyId = companyId;
	}

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}

	public String getCompanyLoc() {
		return companyLoc;
	}

	public void setCompanyLoc(String companyLoc) {
		this.companyLoc = companyLoc;
	}

}

@Named
@Path("/")
public class CompanyRest {

	private long id = 1;

	@Inject
	private RestTemplate restTemplate;

	@GET
	@Path("company")
	@Produces(MediaType.APPLICATION_JSON)
	public Company submitCompany(@QueryParam("idStore") long idStore,
			@QueryParam("idProduct") long idProduct,
			@QueryParam("stock") long stock) {

		Company company = new Company();

        if(isPortInUse("localhost", 8081)){
		Store store = restTemplate.getForObject(
				"http://localhost:8081/store?id={id}", Store.class, idStore);
           company.setStore(store);

         }
         if(isPortInUse("localhost", 8082)){
		Product product = restTemplate.getForObject(
				"http://localhost:8082/product?id={id}", Product.class,
				idProduct);
               company.setProduct(product);
         }

		company.setCompanyId(id);
		company.setStock(stock);
		company.setStockDate(new Date());

		id++;

		return company;
	}
    private boolean isPortInUse(String host, int port) throws Exception{
	  // Assume no connection is possible.
	  boolean result = false;

	  try {
	    (new Socket(host, port)).close();
	    result = true;
	  }
	  catch(SocketException e) {
	    // Could not connect.
		  e.printStackTrace();
	  }

	  return result;
	}
}

“isPortInUse(<host_name>, <port_number>)” is used to check the service if the connected microservice is broken.

Solution

Create

  • Centralized router in-between all services
  • Throw Exceptions into the queues (bunch of exceptions in memcache)
  • Queues in-between services provide buffers that “smooth internal traffic”

The major benefits of microservices are that these services can work independently and together, posing recurring challenges.

Since each part works independently, there is the risk of latency when each piece is brought together.

We can create a circuit breaker which acts like a discovery service, where one microservice realizes another is “sick” and notifies the main circuit breaker. From that point on, a microservice will be able to check the service discovery to determine if the microservice it is connected to is broken, in order to prevent calls being made to or from the said microservice. Setting a “time out” for about ten minutes is recommended.

Conclusion

  • Building and scaling the teams
  • It makes your app more scalable with smaller teams, enabling modularity and is more open to generic changes
  • Uses a smaller codebase
  • Creates a gatekeeper to facilitate one service contacting the database schema at once instance
  • The key benefits of microservice is it eases scaling your engineering team larger [and] your application
  • Microservices often experience compatibility issues, as these services built by different teams on top of different technologies leading to an unstable environment where people are building in different directions.
  • There are methods to deal with such problems and the five most common challenges of using microservices are:
    • Building Microservices First
    • Information Barriers to Productivity
    • How Do Your Services Find Each Other?
    • How Can Services Communicate with Each Other?
    • Decentralized Data Isn’t Always a Positive
  • Difference between SOA and Microservices:
    • Microservices also lend themselves to agile, scrum and continuous delivery software development processes with shorter life cycles
    • This architecture distinguishes itself from service-oriented architecture (SOA) because each microservice belongs to one application only and not multiple

References

  • https://blog.heroku.com/archives/2015/1/20/why_microservices_matter
  • https://devcentral.f5.com/articles/why-microservices-are-driving-operationalization-of-the-network
  • https://www.youtube.com/watch?v=I56HzTKvZKc
  • http://nordicapis.com/microservices-architecture-the-good-the-bad-and-what-you-could-be-doing-better/


This post first appeared on Front-end Code Review & Validation Tools | Treselle Systems, please read the originial post: here

Share the post

MicroServices on the Move

×

Subscribe to Front-end Code Review & Validation Tools | Treselle Systems

Get updates delivered right to your inbox!

Thank you for your subscription

×