DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Aggregating REST APIs Calls Using Apache Camel
  • Microservices With JHipster
  • How to Setup the Spring Cloud Config Server With Git

Trending

  • Building Resilient Identity Systems: Lessons from Securing Billions of Authentication Requests
  • Unlocking the Potential of Apache Iceberg: A Comprehensive Analysis
  • How to Perform Custom Error Handling With ANTLR
  • Secure by Design: Modernizing Authentication With Centralized Access and Adaptive Signals
  1. DZone
  2. Coding
  3. Java
  4. How to Develop Microservices With Spring Cloud and Netflix Discovery

How to Develop Microservices With Spring Cloud and Netflix Discovery

By 
Abhijit Pritam Dutta user avatar
Abhijit Pritam Dutta
·
Jun. 18, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
9.8K Views

Join the DZone community and get the full member experience.

Join For Free

Today I am going to provide you an example of a small microservices based application, where I am going to implement a Eureka discovery server to register all the microservices application in it, so that each of these services can be accessible from all the microservices applications registered with Discovery Server. 

For this example, we are going to create total four microservices applications/services. 

  1. discovery-service – A eureka Discovery server.
  2. library-service ( a rest service, a discovery client as well).
  3. book-service (a rest service, a discovery client as well).
  4. read-service – A rest service which will consume both book-service and library-library service. This is also a discovery client which will register itself in discovery server. 

Here, the role of Discovery Server is, to register all the client applications in it so that their information can be globally available to all the registered client applications. So this Discovery Server will allow microservices to consume other microservices without knowing their exact location i.e. their host id and port number. Even if you decide to move an application/service to a different server, no application previously consuming your service will be impacted. 

Because from discovery server they will know the new location (new host id and port) of your service which has been moved to a different server. Suppose you have decided to move your application from an Indian server (http://myindia.gov.in:9001) to an US server (http://your-us.gov.us:99013) you do not need to inform any of the applications previously consuming your services. They will get to know it automatically from discovery server and they even do not need to do anything at their end. 

Please see the below diagram to understand how a discovery server serve a client application registered in it. For example read-service need to consume services from book-service and library-service, now how will read-service get the host name and port number of both these application to consume? It will be provided by discovery service as both book-service and library-service already registered themselves in discovery-service.

Eureka Discovery Server

To read more about Spring cloud Netflix you can visit https://cloud.spring.io/spring-cloud-netflix/2.0.x/single/spring-cloud-netflix.html.

Let us develop the entire project step-by-step.

Step 1

First, we will create discovery-service which is a Eureka discovery server. If you are new to Spring Boot, you can follow my article https://github.com/prateekparallel/spring-boot-rest-2 to create a Spring Boot application. Now, click https://start.spring.io/ and open Spring Initializr. Now do exactly what I am doing in the below screen shot. (Group, Artifact, etc fill as per your choice):

Spring initializr

Click ADD DEPENDENCIES and select all the dependencies (in search bar just type the dependency – Eureka and Actuator and select it one at a time. Do not select Eureka client)

Adding dependencies

Now click the GENERATE button to generate the project and save it to your machine and import it as maven project to your tool (here I am using Eclipse).

In eclipse right click on project explorer and select import and select -

Creating Java project


Now, open the Java file, DemoDiscoveryServerApplication.java, and add @EnableEurekaServer in it:

Java
 




xxxxxxxxxx
1
15


 
1
package com.bhaiti.jorhat.demodiscoveryserver;
2
 
          
3
import org.springframework.boot.SpringApplication;
4
import org.springframework.boot.autoconfigure.SpringBootApplication;
5
 
          
6
@SpringBootApplication
7
@EnableEurekaServer
8
public class DemoDiscoveryServerApplication {
9
 
          
10
    public static void main(String[] args) {
11
        SpringApplication.run(DemoDiscoveryServerApplication.class, args);
12
    }
13
 
          
14
}
15
 
          



Now, rename your application.properties  file to application.yml and add the following:

YAML
 




xxxxxxxxxx
1
13


 
1
server.port: 9001
2
 
          
3
spring.application.name: demo-discovery-server
4
 
          
5
eureka:
6
 server:
7
 evictionIntervalTimerInMs: 3000
8
 response-cache-update-interval-ms: 3000
9
 
          
10
 client:
11
 registerWithEureka: false
12
 fetchRegistry: false
13
 service-url.defaultZone: http://localhost:${server.port}/eureka



You can see above we assigned false to both registerWithEureka and fetchRegistry. The reason is we do not want to register this application in itself as this is a discovery server to register discovery client only. For detail about configuration please check in this repository. 

Your discovery server is ready now. Just compile it and run it in command prompt.

In the project home directory just execute the below command:

mvnw clean package

Now, start the discovery server

java -jar target/demo-discovery-server-0.0.1-SNAPSHOT.jar

<>now you can check the dashboard of Eureka discovery server by hitting http://localhost:9001


Now you do not see any client in it. Let’s develop our first client application book-service

Step 2: Create a REST service application call book-service. To create the project , follow below steps

Please notice here we have selected dependency Eureka Client this time, as our REST service application is also a Eureka Client as well. Generate the project and import to your eclipse as maven project.

Now change the application.property to application.yml and modify it like below-

YAML
 




xxxxxxxxxx
1
12


 
1
server.port: 9901
2
 
          
3
spring:
4
 application.name: book-service 
5
 
          
6
eureka:
7
 client:
8
 serviceUrl:
9
 defaultZone: http://localhost:9001/eureka/
10
 registryFetchIntervalSeconds: 1
11
 instance:
12
 leaseRenewalIntervalInSeconds: 1



Now in the above you can see that defaultZone is assigned with the address of our discovery server. So this discovery client will register itself in the discovery server which will be listing at http://localhost:9001. Now we have to do some coding in our REST application book-service. First open BookServiceApplication.java file and add @EnableDiscoveryClient in it to activate the discovery client.

Java
 




xxxxxxxxxx
1
16


 
1
package com.bhaiti.jorhat.book.bookservice;
2
 
          
3
import org.springframework.boot.SpringApplication;
4
import org.springframework.boot.autoconfigure.SpringBootApplication;
5
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6
 
          
7
@SpringBootApplication
8
@EnableDiscoveryClient
9
public class BookServiceApplication {
10
 
          
11
    public static void main(String[] args) {
12
        SpringApplication.run(BookServiceApplication.class, args);
13
    }
14
 
          
15
}
16
 
          



Now create a new java class call BookService.java like below

And add the following code in it

Java
 




xxxxxxxxxx
1
14


 
1
package com.bhaiti.jorhat.book.bookservice;
2
 
          
3
import java.util.Arrays;
4
import java.util.List;
5
 
          
6
public class BookService {  
7
    private static List<String> bookList = Arrays.asList("Book1","Book2","Book3");
8
 
          
9
    public static List<String> getBookList() {
10
        return bookList;
11
    }
12
 
          
13
}
14
 
          



Now create a controller class like below:-

Java
 




xxxxxxxxxx
1
18


 
1
package com.bhaiti.jorhat.book.bookservice;
2
 
          
3
import java.util.List;
4
 
          
5
import org.springframework.http.ResponseEntity;
6
import org.springframework.web.bind.annotation.GetMapping;
7
import org.springframework.web.bind.annotation.RestController;
8
 
          
9
@RestController
10
public class BookController {
11
 
          
12
    @GetMapping("/books")
13
    public ResponseEntity<List<String>> getBookList(){ 
14
        return ResponseEntity.ok(BookService.getBookList());    
15
    }
16
    
17
}
18
 
          



Add the below dependency in your pom.xml file

XML
 




xxxxxxxxxx
1
12


 
1
<dependency>
2
    <groupId>org.springframework</groupId>
3
    <artifactId>spring-web</artifactId>
4
</dependency>
5
<dependency>
6
    <groupId>org.springframework.boot</groupId> 
7
    <artifactId>spring-boot-starter-web</artifactId>
8
</dependency>
9
<dependency>
10
 <groupId>org.springframework.boot</groupId>
11
 <artifactId>spring-boot-starter</artifactId>
12
</dependency>



Now compile it and run it like below:-

Shell
 




xxxxxxxxxx
1


 
1
cd book-service
2
mvnw clean package
3
java -jar target/book-service-0.0.1-SNAPSHOT.jar


 

Now refresh eureka (discovery server) dashboard, you can see that book-service has been registered in it. 

Step 3: Now create library-service application. Just repeat step 2 and create a project and import it to you development area.


Now update your pom.xml exactly like you did for book-service.

Now add two classes respectively LibraryService.java and LibraryController.java

First modify your LibraryServiceApplication.java and add @EnableDiscoveryClient 

Java
 




xxxxxxxxxx
1
10


 
1
@SpringBootApplication
2
@EnableDiscoveryClient
3
public class LibraryServiceApplication {
4
 
          
5
    public static void main(String[] args) {
6
        SpringApplication.run(LibraryServiceApplication.class, args);
7
    }
8
 
          
9
}
10
 
          



Now create LibraryService.java and modify it like below

Java
 




xxxxxxxxxx
1
22


 
1
package com.bhaiti.uk.global.repo;
2
 
          
3
import java.util.HashMap;
4
import java.util.Map;
5
 
          
6
public class LibraryService {
7
    
8
    private static Map<String, String> libList;
9
    
10
    static {
11
        libList = new HashMap<String, String>();
12
        libList.put("Book1", "Library3");
13
        libList.put("Book2", "Library1");
14
        libList.put("Book3", "Library2");
15
    }
16
 
          
17
    public static Map<String, String> getLibList() {
18
        return libList;
19
    }
20
 
          
21
}
22
 
          



Now create LibraryController.java and modify it like below

Java
 




xxxxxxxxxx
1
18


 
1
package com.bhaiti.uk.global.repo;
2
 
3
import java.util.Map;
4
 
5
import org.springframework.http.ResponseEntity;
6
import org.springframework.web.bind.annotation.GetMapping;
7
import org.springframework.web.bind.annotation.RestController;
8
 
9
 
10
@RestController
11
public class LibraryController {
12
 
13
       @GetMapping("/librarys")
14
       public ResponseEntity<Map<String, String>> getBookList(){ 
15
              return ResponseEntity.ok(LibraryService.getLibList()); 
16
       }
17
       
18
}



Now, rename your application.properties file to application.yml and add the following:

YAML
 




xxxxxxxxxx
1
12


 
1
server.port: 9902
2
 
          
3
spring:
4
 application.name: library-service 
5
 
          
6
eureka:
7
 client:
8
 serviceUrl:
9
 defaultZone: ${EUREKA_URI:http://localhost:9001/eureka}
10
 registryFetchIntervalSeconds: 1
11
 instance:
12
 leaseRenewalIntervalInSeconds: 1


 

Compile and run the application:

Shell
 




xxxxxxxxxx
1


 
1
cd library-service
2
mvnw clean package
3
java -jar target/library-service-0.0.1-SNAPSHOT.jar



Now, refresh the Eureka dashboard, and you can see that your library-service also listed in it.

Running Eureka dashboard

Step 5: Now we are going to create our last REST service - read-service. Now create it and import it to your eclipse. Please notice we are adding one more dependency here i.e. OpenFeign.

Creating new Maven project

Now change the name of file application.properties file to application.yml and add the following:

YAML
 




xxxxxxxxxx
1
12


 
1
server.port: 9903
2
 
          
3
spring:
4
 application.name: library-service 
5
 
          
6
eureka:
7
 client:
8
 serviceUrl:
9
 defaultZone: ${EUREKA_URI:http://localhost:9001/eureka}
10
 registryFetchIntervalSeconds: 1
11
 instance:
12
 leaseRenewalIntervalInSeconds: 1


 

Modify your pom.xml exactly the same way as you did for library-service.

Here, in read-service, we are going to consume both book-service and library-service. To call the REST service API of library-service and book-service we will implement a Feign Client here.

First modify your ReadServiceApplication.java like below:

Java
 




xxxxxxxxxx
1


 
1
@SpringBootApplication
2
@EnableDiscoveryClient
3
public class ReadServiceApplication {


 

Now, create our Feign Clients here. Create two interface respectively BookClient.java and LibraryClient.java, and modify them like below:

Java
 




xxxxxxxxxx
1
16


 
1
package com.bhaiti.jorhat.read;
2
 
          
3
import java.util.List;
4
 
          
5
import org.springframework.cloud.openfeign.FeignClient;
6
import org.springframework.web.bind.annotation.GetMapping;
7
 
          
8
 
          
9
@FeignClient("book-service")
10
public interface BookClient {
11
    
12
    @GetMapping("/books")
13
        List<String> getBookList(); 
14
    
15
}
16
 
          



Java
 




xxxxxxxxxx
1
13


 
1
package com.bhaiti.jorhat.read;
2
 
          
3
import java.util.Map;
4
 
          
5
import org.springframework.cloud.openfeign.FeignClient;
6
import org.springframework.web.bind.annotation.GetMapping;
7
 
          
8
@FeignClient("library-service")
9
public interface LibraryClient {
10
    @GetMapping("/librarys")
11
    Map<String, String> getLibraryList();
12
}
13
 
          



The beauty of using FeignClient is that you don’t need to know the host name and port number of the application where you are going to make a REST call. Here to make a REST call to book-service we are not using an URI. Feign use Ribbon to get everything requires for the REST call and gets all the detail about book-service and library-service(host and port) from discovery server. Because book-service and library-service are not only a REST based application but also a discovery client too, hence it can retrieve information about other clients of discovery server. 

To read more about FeignClient visit https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html and https://cloud.spring.io/spring-cloud-openfeign/reference/html/

Suppose you don’t want to use a FeignClient and want to make a REST call with http connection object or with RestTemplate, in such situation you can use the below codes to get the application’s host name and port number.

Java
 




xxxxxxxxxx
1
12


 
1
@Autowired
2
private EurekaClient eurekaClient;
3
 
          
4
public String getBaseUrl() {
5
 Application application = eurekaClient.getApplication("book-service");
6
 InstanceInfo instanceInfo = application.getInstances().get(0);
7
  
8
 String hostname = instanceInfo.getHostName();
9
 int port = instanceInfo.getPort();
10
 
          
11
 return "http://" + hostname + ":" + port;
12
}


 

(Above codes are out of the scope of this article. I am discussing about it in my article SSL based/Secured FeignClient…) 

Now add the below controller 

Java
 




xxxxxxxxxx
1
40


 
1
package com.bhaiti.jorhat.read;
2
 
          
3
 
          
4
import java.util.List;
5
import java.util.Map;
6
 
          
7
import org.springframework.beans.factory.annotation.Autowired;
8
import org.springframework.http.ResponseEntity;
9
import org.springframework.web.bind.annotation.GetMapping;
10
import org.springframework.web.bind.annotation.PathVariable;
11
import org.springframework.web.bind.annotation.RestController;
12
 
          
13
 
          
14
@RestController
15
public class ReadServiceController {
16
    
17
    @Autowired
18
    BookClient bookClient;
19
    
20
    @Autowired
21
    LibraryClient libraryClient;
22
 
          
23
    @GetMapping(path= "/read/{bookName}", produces = "application/json")
24
    public ResponseEntity<String> getReadingLocation(@PathVariable(value = "bookName") String bookName){
25
        String response;
26
        
27
        List<String> bookList = bookClient.getBookList(); 
28
        if(bookList.contains(bookName)) {
29
            Map<String, String> libList = libraryClient.getLibraryList();
30
            response = "You can read this book - " + bookName 
31
                    + " at this Library - " + libList.get(bookName);
32
        }
33
        else {
34
            response = "Your Book - " + bookName + " is not currently available in Libaries";
35
        }
36
        return ResponseEntity.ok().body(response);  
37
    }
38
}
39
 
          
40
 
          



And finally modify the ReadServiceApplication.java like below:

Java
 




xxxxxxxxxx
1
18


 
1
package com.bhaiti.jorhat.read;
2
 
          
3
import org.springframework.boot.SpringApplication;
4
import org.springframework.boot.autoconfigure.SpringBootApplication;
5
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6
import org.springframework.cloud.openfeign.EnableFeignClients;
7
 
          
8
@SpringBootApplication
9
@EnableFeignClients
10
@EnableDiscoveryClient
11
public class ReadServiceApplication {
12
 
          
13
    public static void main(String[] args) {
14
        SpringApplication.run(ReadServiceApplication.class, args);
15
    }
16
 
          
17
}
18
 
          



Now, your microservices application is fully ready for testing. 

First compile it and run it and check the Eureka server.

Shell
 




x


 
1
cd read-service
2
mvnw clean package
3
java -jar target/read-service-0.0.1-SNAPSHOT.jar



Now, hit the below URL and check

Checking local URL

It will display the below line in your browser.

Just change the name of the book to Book1 and Book2 and Book4 and test for each entry. Source code of this project is available here - https://github.com/prateekparallel/microservices-example.

Hope you enjoyed this tutorial.

Discovery (law) Spring Framework microservice Spring Cloud application Java (programming language) REST Web Protocols Host (Unix) Dependency

Opinions expressed by DZone contributors are their own.

Related

  • Distributed Tracing System (Spring Cloud Sleuth + OpenZipkin)
  • Aggregating REST APIs Calls Using Apache Camel
  • Microservices With JHipster
  • How to Setup the Spring Cloud Config Server With Git

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!