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..
- eureka
server + api gateway (Zuul proxy + Ribbon internally) for dynamic routing and client
side load balancing
- eureka
server + Ribbon client side load balancing without api gateway
- eureka
server + api gateway (Zuul proxy + Ribbon internally) for dynamic routing and client
side load balancing + Hystrix (Fault Torrance) using fallback method
- 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 Eureka, Ribbon 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.
- eureka-server
- api-gateway
- gallery-service
- image-service
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.
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.
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).
































