Microservices: Declare Zuul routes with Eureka serviceId (Spring Cloud + Zuul + Eureka)

 

In a previous article, we have declared/defined the Zuul routes by providing the service details (URL) manually (Click here to visit that article). That means we have provided the domain name or ip address  and port number of each service.  Just think of a situation where the application contains a large number of microservices. Do you think that it is practical to find (manually) the server details (ip address/domain) and port details of every service? If that is difficult, then how do we declare the zuul route mapping to expose each service through the Zuul Proxy?

The solution is to perform the Zuul routes mapping with serviceId registered in the Eureka Server“.

 

Here i am not going to discuss about the importance of Netflix Zuul Proxy or Netflix Eureka server.  I have already written two separate articles on both of those areas. If you need to refresh your knowledge on those areas, please refer the relevant articles.

 

What we are going to do here?

In order to demonstrate the serviceId based Zuul route mapping, we will be creating following set of applications.

  • Eureka Server :- Spring Boot Applciation to act as Eureka Server. All the microservices will be registered here.
  • Zuul Proxy: – Spring Boot Application to act as Zuul Reverse Proxy. This is the centralized gateway for directing all the requests for the misroservices. Zuul proxy will communicate with Eureka server to get the details (ip address and port) of the relevant microservice for delegating the client request.
  • student-service :- just dummy microservice for representing the backend business service.

 

Lets create them one by one. The full source code of this application can be found at GitHub.

 

Eureka Server

Eureka Server is just another spring boot application with Spring Cloud Netflix Eureka dependency. Then annotate the main spring boot configuration class with @EnableEurekaServer annotation.

Therefore create a spring boot application with Eureka dependency.

eureke-server

 

Then  add the @EnableEurekaServer annotation to the main Spring Boot Application configuration class (That is the class annotated with @SpringBootApplication annotation)

 

 

application.properties (Eureka Server)

This is the Eureka server application and it is a spring cloud managed service. Therefore it has the similar nature as other microservices. In microservice architecture, every microservice(spring cloud service) should be registered themselves with Eureka server to make them discoverable (through Eureka server).  Since this is the Eureka server, it does not need to register. So we have disabled the registration as follows. Otherwise the Eureka server will register with itself.

eureka.client.register-with-eureka=false

 

On the other hand, Eureka server does not need to fetch the information of the registered services from itself (from the registry available on itself). So we have disable that feature too.

eureka.client.fetch-registry=false

 

Go to the source directory of the Eureka server application and execute the folllowing command to run the application.

mvn spring-boot:run

 

The application will be up and run on port 8761 as configured.

Screen Shot 2018-03-15 at 11.39.24 PM.png

 

You can see that Eureka server does not have any registered services (No instances available).  Lets create a sample service and register it with Eureka server.

 

Student Service

Here we are going to create a simple application with few REST endpoints. We will register this application in the Eureka server as a Eureka Discoverable Client.

Create another spring boot application with following dependencies.

  • Eureka Discovery
  • Actuator
  • Web

 

Screen Shot 2018-03-12 at 3.03.32 PM.png

 

Note: here i am just adding only the selected source code. If you want to refer the full source code, please clone it from GitHub.

 

After creating the project, your pom.xml should contains the following dependencies.

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
 </dependency>

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>

 

 

Why the Actuator dependency is added here?

Actuator contains the health indicators used by Eureka Server to determine the health of the service. (By default, Eureka server set the URL to the /info of the service to check the health)

 

@EnableDiscoveryClient annotation has been added in the main spring boot configuration class to make the service as a Discoverable client.

 

 

Sometimes you might have noticed that @EnableEurekaClient has been used instead of @EnableDiscoveryClient annotation. Lets look at their difference.

@EnableDiscoveryClient  annotation can work with any Discovery Client implementations which implements in your project ( Eureka, Consul, Zookeeper ) You can also use @EnableEurekaClient annotation but it works only with Eureka Discovery Client implementation.

@EnableDiscoveryClient lives in spring-cloud-commons and picks the implementation on the classpath. @EnableEurekaClient lives in spring-cloud-netflix and only works for Eureka.

 

application.properites (student-service)

 

spring.application.name = student-service

The service will be registered in the Eureka Server with name “student-service“. The other registered services will use this name as the service-id to access this service.

 

eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/

This is the URL of the Eureka deployment. You have to mention location of the Eureka Server by using defaultZone property

The service can be up and run with following command.

mvn spring-boot:run

 

 

Then the service will be up and run on the port 8098 of your local machine. If you look at the StudentController.java, you can find more REST endpoints.

 

Lets check whether the service is up and running with following endpoint.

http://localhost:8098/students/1

Screen Shot 2018-03-18 at 9.06.31 AM.png

 

 

Is Application Registered in Eureka?

Now it is time to check whether the application is really registered in Eureka server.  Lets open the Eureka admin panel  (http://localhost:8761/) check whether it is already registered.

 

Screen Shot 2018-03-17 at 12.19.08 PM.png

 

You can see that it is registered with name “STUDENT-SERVICE”  and listed under the list of “Instances currently registered with Eureka“.

student-service” is the name provided by the spring application with property spring.application.name in application.properties.

 

Zuul Reverse Proxy

This is the most awaiting and focused part of this article. We are going to create a Zuul Proxy application that fetches the registered microservices details from the Eureka server.  In here, the route mapping of the Zuul Proxy will be based on the seviceId of the Eureka Server instead of fixed URI approach. (I have done a sperate article on Zuul Proxy route mapping with fixed URI)

 

So we should create the spring boot application with following two dependencies.

  • Zuul :- dependency for making the application as Zuul proxy application. This will inherit the features and behaviors of the Netflix Zuul Proxy.
  • Eureka Discovery :- dependency for registering the application as Eureka Discoverable Client.

 

Lets create another spring boot application with Zuul dependency and Eureka Discovery.

Screen Shot 2018-03-13 at 12.36.44 AM.png

 

Once the project is created, add following two annotations for the main spring boot configuration class.

  • @EnableZuulProxy :- enables the Zuul proxy features.
  • @EnableDiscoveryClient :- making the application as a Eureka Discoverable client.

 

After adding above annotations, your main spring boot configuration class should looks like below.

 

 

Now lets move forward to do the route mapping with Eureka based servicedId.

 

Zuul Route Mapping with Eureka ServiceId

If you have gone through the previous article (click here to view it) about Zuul, you may have an idea of how to do the route mapping with URI.

Here we are going to do the route mapping based on serviceId of the Eureka server instead of that URI based approach.  please refer the application.properties file of the Zuul proxy application.

 

server.port = 2020

Zuul Proxy will be up and running on port 2020.

 

eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/

This contains the URL of the Eureka Server.

 

eureka.client.registerWithEureka=false

In order to retrieve/fetch the registered service details, Zuul Proxy does not need to register with Eureka Server. Therefore the Zuul proxy will not register with the Eureka server.

 

eureka.client.fetchRegistry=true

This will allow the Zuul Proxy to retrieve the registered service details from the Eureka server.

 

zuul.routes.student-service.path=/student-api/**
zuul.routes.student-service.serviceId=STUDENT-SERVICE

If any traffic (or request) comes to the /student-api/  will be directed to the service registered with service-id  “STUDENT-SERVICE”.

 

Testing

Lets send the Request to the all the defined in the StudentController through the Zuul Proxy.

 

GET /name  http://localhost:2020/student-api/name

Screen Shot 2018-04-03 at 11.33.21 PM.png

 

 

GET /students/{id}  http://localhost:2020/student-api/students/1

Screen Shot 2018-04-03 at 11.31.27 PM.png

 

 

GET /courses/{course_id}/students   
http://localhost:2020/student-api/courses/1/students

 

Screen Shot 2018-04-03 at 11.32.07 PM.png

 

 

 

GET  /departments/{department_id}/courses/{course_id}/students
http://localhost:2020/student-api/departments/1/courses/2/students

 

Screen Shot 2018-04-03 at 11.31.37 PM.png

 

As you can see that we have used Eureka based serviceId for route mapping in Zuul Proxy.

 

2 thoughts on “Microservices: Declare Zuul routes with Eureka serviceId (Spring Cloud + Zuul + Eureka)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s