Sunday, 10 March 2019

Microservices Architecture



Building Micro-services with Spring Boot





In the series of building micro-services application we will cover below Netflix OSS components combination. In this post we will cover first option mentioned below, rest of the options we will explore in next post..
  1. eureka server + api gateway (Zuul proxy + Ribbon internally) for dynamic routing and client side load balancing
  2. eureka server + Ribbon client side load balancing without api gateway
  3.  eureka server + api gateway (Zuul proxy + Ribbon internally) for dynamic routing and client side load balancing + Hystrix (Fault Torrance) using fallback method
  4. eureka server + api gateway (Zuul proxy + Ribbon internally) for dynamic routing and client side load balancing + Hystrix (Fault Torrance)  + KAFKA for integration pattern



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



The table below maps the generic components in the operations model to the actual components that we will use throughout this blog series:







In this blog post we will cover EurekaRibbon and to Zuul:

·         Netflix Eureka - Service Discovery Server Netflix Eureka allows microservices to register themselves at runtime as they appear in the system landscape.

·         Netflix Ribbon - Dynamic Routing and Load Balancer Netflix Ribbon can be used by service consumers to lookup services at runtime. Ribbon uses the information available in Eureka to locate appropriate service instances. If more than one instance is found, Ribbon will apply load balancing to spread the requests over the available instances. Ribbon does not run as a separate service but instead as an embedded component in each service consumer.

·         Netflix Zuul - Edge Server Zuul is (of course) our gatekeeper to the outside world, not allowing any unauthorized external requests pass through. Zulu also provides a well known entry point to the microservices in the system landscape. Using dynamically allocated ports is convenient to avoid port conflicts and to minimize administration but it makes it of course harder for any given service consumer. Zuul uses Ribbon to lookup available services and routes the external request to an appropriate service instance. In this blog post we will only use Zuul to provide a well-known entry point, leaving the security aspects for coming blog posts.

Let’s understand how nextfilx oss component works.





Step-1:  Service gets registered with Eureka Server, in this example 3 instances of services are running and registered with eureka server. Eureka server always up to date that how many instances are up and down.

Step-2 : When any client make request, it comes through gatekeeper Zuul and its responsibility is dynamic routing with assigning port at runtime and for this it internally uses Ribbon, since Ribbon always gets synched with Eureka server that how many active services instance are there. So at any moment of time Ribbon are in state with active running instance. So with the help of Ribbon, Zuul assign active instance port to request and route it to actual running instance.


Step-3: Multiple client request.


Now let’s understand it through design and develop microservice using below tech stack,

·         Spring Boot 2.1.3.RELEASE
·         Spring Cloud Netflix Eureka for discovery service
·         Zuul API Gateway for Routing
·         Ribbon for client load balancing
·         Maven for dependency management




In this post we will create below component in sequence.
  1. eureka-server
  2. api-gateway
  3. gallery-service
  4. image-service

  
 1.       eureka-server
It’s the naming server, or called service registry. It’s duty to give names to each microservice. Why?
1.      No need to hardcode the IP addresses of microservices.
2.      What if services use dynamic IP addresses; when autoscaling.
So, every service registers itself with Eureka, and pings Eureka server to notify that it’s alive.
If Eureka server didn’t receive any notification from a service. This service is unregistered from the Eureka server automatically.














Maven dependency for Eureka Server






application.properties file entry for eureka server





Adding @EnableEurekaServer annotation to the main class, will make this module as Eureka server.


Start the eureka-server and open http://localhost:8761/. You’ll get Spring Eureka dashboard. You can easily get information like Registered eureka clients, Memory usage, CPU details and etc.


 2. api-gateway

When calling any service from the browser, we can’t call it by it’s name as we did from Gallery service — This is used internally between services.
And as we run more instances of services, each with a different port numbers, So, now the question is: How can we call the services from the browser and distribute the requests among their instances running at different ports?
Well, a common solution is to use a Gateway.
A gateway is a single entry point into the system, used to handle requests by routing them to the corresponding service. It can also be used for authentication, monitoring, and more.

What’s Zuul?

It’s a proxy, gateway, an intermediate layer between the users and your services.
Eureka server solved the problem of giving names to services instead of hardcoding their IP addresses.
But, still, we may have more than one service (instances) running on different ports. So, Zuul …
1.      Maps between a prefix path, say/gallery/** and a service gallery-service. It uses Eureka server to route the requested service.
2.      It load balances (using Ribbon) between instances of a service running on different ports.
3.      What else? We can filter requests, add authentication, etc.


Let’s create api-gateway






Maven dependency



application.properties file


It’s worth mentioning that Zuul acts as a Eureka client. So, we give it a name, port, and link to Eureka server (same as we did with image service).

Let’s make this module as Zuul and eureka client by adding below annotation
@EnableZuulProxy To Main Application class.




 3. image-service


This is very simple client service which will act as data source for images each image has an id, title, and url and port.










maven-dependency




application.properties file



Enable eureka Client using @EnableDiscoveryClient



Now, our image service is going to expose some data through endpoints, right?. So, we need to create a controller, and define the action methods.



4. gallery-service

The Eureka client service can be also a REST client that calls (consumes) other services (REST API services) in our microservice application.
So, for example, the gallery service calls image service to get a list of all images, or maybe only images created during a specific year.
The calls from this REST client to the other services can be done using:
1.       RestTemplate. An object that’s capable of sending requests to REST API services.
2.       FeignClient (acts like a proxy), and provides another approach to RestTemplate.
Both, load balance requests across the services.







Maven dependency




In the spring boot main application class, besides enabling the eureka client, we need to create a bean for RestTemplate to call the image service.





In the controller, call image service using RestTemplate and return the result.





Ok, here’s one thing to note. Since we are using restTemplate — which in turn uses Eureka Server for naming of services, and Ribbon for load balancing. So, we can use the service name (like image-service) instead of localhost:port


Testing our Microservices

Ok. So, we have a service discovery; Eureka server. Two services; image and gallery. And a gateway; Zuul.

To test our application, run eureka server, zuul, and then the two services. Then, go to Eureka Server running at localhost:8761, you should see the running services.

To run multiple instances. In eclipse, go to Run →Configurations/Arguments →VM options and add -Dserver.port=5555






















As you can see gallery-service is running on two different port 8098 and 5555 and image service is running on two different port 4444 and 3333.

Now hit http://localhost:2020/gallery-api/1 on browser multiple time.

Running on port 4444


Running on port 3333




You can download source code from below github url



In next post we will see use of Ribbon without using Zuul(api gateway).