Part 1: Creating microservice using Spring Cloud, Eureka and Zuul

Spring framework provides set of libraries for creating microservices in Java. They are a part of Spring Cloud project. Today I’m going to show you how to create simple microservices using Spring Boot and following technologies:

  • Zuul –  gateway service that provides dynamic routing, monitoring, resiliency, security, and more
  • Ribbon – client side load balancer
  • Feign – declarative REST client
  • Eureka – service registration and discovery
  • Sleuth – distributed tracing via logs
  • Zipkin – distributed tracing system with request visualization.

Sample application is available at Here’s picture with application architecture. Client calls endpoint available inside customer-service which stores basic customer data via Zuul gateway. This endpoint interacts with account-service to collect information about customer accounts served by endpoint in account-service. Each service registering itself on Eureka discovery service and sending its logs to Zipkin using spring-cloud-sleuth.


This is account-service controller. We use findByCustomer method for collecting customer accounts by his id.

public class Api {
	private List<Account> accounts;

	protected Logger logger = Logger.getLogger(Api.class.getName());

	public Api() {
		accounts = new ArrayList<>();
		accounts.add(new Account(1, 1, "111111"));
		accounts.add(new Account(2, 2, "222222"));
		accounts.add(new Account(3, 3, "333333"));
		accounts.add(new Account(4, 4, "444444"));
		accounts.add(new Account(5, 1, "555555"));
		accounts.add(new Account(6, 2, "666666"));
		accounts.add(new Account(7, 2, "777777"));

	public Account findByNumber(@PathVariable("number") String number) {"Account.findByNumber(%s)", number));
		return -> it.getNumber().equals(number)).findFirst().get();

	public List<Account> findByCustomer(@PathVariable("customer") Integer customerId) {"Account.findByCustomer(%s)", customerId));
		return -> it.getCustomerId().intValue()==customerId.intValue()).collect(Collectors.toList());

	public List<Account> findAll() {"Account.findAll()");
		return accounts;

This is customer-service controller. There is findById method which interacts with account-service using Feign client.

public class Api {

	private AccountClient accountClient;

	protected Logger logger = Logger.getLogger(Api.class.getName());

	private List<Customer> customers;

	public Api() {
		customers = new ArrayList<>();
		customers.add(new Customer(1, "12345", "Adam Kowalski", CustomerType.INDIVIDUAL));
		customers.add(new Customer(2, "12346", "Anna Malinowska", CustomerType.INDIVIDUAL));
		customers.add(new Customer(3, "12347", "Paweł Michalski", CustomerType.INDIVIDUAL));
		customers.add(new Customer(4, "12348", "Karolina Lewandowska", CustomerType.INDIVIDUAL));

	public Customer findByPesel(@PathVariable("pesel") String pesel) {"Customer.findByPesel(%s)", pesel));
		return -> it.getPesel().equals(pesel)).findFirst().get();

	public List<Customer> findAll() {"Customer.findAll()");
		return customers;

	public Customer findById(@PathVariable("id") Integer id) {"Customer.findById(%s)", id));
		Customer customer = -> it.getId().intValue()==id.intValue()).findFirst().get();
		List<Account> accounts = accountClient.getAccounts(id);
		return customer;
public interface AccountClient {

	@RequestMapping(method = RequestMethod.GET, value = "/accounts/customer/{customerId}")
	List<Account> getAccounts(@PathVariable("customerId") Integer customerId);


To be able to using Feign client we only have to enable it in our main class.

package pl.piomin.microservices.customer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

public class Application {

	public static void main(String[] args) {, args);

There is also important configuration inside application.yml in customer-service. The ribbon load balancer needs to be enabled and also I suggest to set lease reneval and expiration on Eureka client to enable unregistration from discovery service when our service is shutting down.

	port: ${PORT:3333}

			defaultZone: ${}/eureka/
		leaseRenewalIntervalInSeconds: 1
		leaseExpirationDurationInSeconds: 2

		enabled: true

Ok, fine. We’ve got our two microservices implemented and configured. But first we have to create and run discovery service based on Eureka server. This functionality is provided by our discovery-service. We only have to import one dependency in our pom.xml called spring-cloud-starter-eureka-server and enable it in application main class using @EnableEurekaServer annotation. Here is configuration of Eureka server in application.yml file:

	port: ${PORT:8761}

		hostname: localhost
		registerWithEureka: false
		fetchRegistry: false
		enableSelfPreservation: false

After running discovery-service we see its monitoring console available on 8761 port. And now let’s run our two microservices on default ports set in their application.yml configuration file and more two instances of them on another ports using -DPORT VM argument, for example account-service on port 2223, and customer-service on port 3334. Now we take o look on Eureka monitoring console: we’ve got two instances of account-service running on 2222, 2223 ports and two instances of customer-service running on 3333, 3334 ports.


We have two instances of each microservice registered on discovery server. But we need to hide our system complexity to the outside world. There should be only one IP address exposed on one port available for inbound clients. That’s why we need API gateway – Zuul. Zuul will forward our request to the specific microservice based on its proxy configuration. Such request will also be load balances by ribbon client. To enable Zuul gateway dependency spring-cloud-starter-zuul should be added inside pom.xml and annotation @EnableZuulProxy in the main class. This is Zuul configuration for ourservices set in application.yml.

	port: 8765

	prefix: /api
			path: /account/**
			serviceId: account-service
			path: /customer/**
			serviceId: customer-service 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>


Like we see Zuul is configured to be available under its default port 8765 and it forwards requests from /api/account/ path to account-service and from /api/customer/ to customer-service. When URL http://localhost:8765/api/customer/customers/1 is call several times we’ll see its load balanced between two instances of each microservice. Also when we shut down one of microservice instance we can take o look that it is unregistered from Eureka server.

In the second part of article I’ll present how to use Spring Cloud Sleuth, Zipkin and ELK. If you are interested in see Part 2: Creating microservices – monitoring with Spring Cloud Sleuth, ELK and Zipkin.


Author: Piotr Mińkowski

IT Architect, Java Software Developer

35 thoughts on “Part 1: Creating microservice using Spring Cloud, Eureka and Zuul”

  1. Thx for this article, I have a question related with how this servers phisically are distributed, if they are in the same ServerAPP or in differents servers or in different services, and what AppServer like GlassFish, Weblogic, WildFly are you using for this example.

    thx a lot from Colombia.

    Liked by 1 person

      1. Nice share.
        I have downloaded your code and ran the services as Spring Boot in STS Spring tool suite (Run As->Spring Boot App) with the following order:
        1. discovery-service
        2. account-service
        3. customer-service
        4. gateway-service
        5. zipkin-service
        Is the order correct ?
        I believe, these services are packaged as jar. And I ran these easily in eclipse/STS.
        I want to deploy these services on external tomcat server.
        Do I need to export all these services as war files and deploy them to tomcat server ?
        How to configure the multiple ports and application/servlet context name as you mentioned .yml files ?
        Please let me know the steps/configuration needed to deploy these services on external tomcat server ?


      2. Well, those services are running on Spring Boot. Tomcat is embedded and is starting with application: java -jar Application. Port can be overriden with VM argument -DPORT. If you would like to deploy it on external Tomcat you have to remove Spring Boot and use stardard Spring Web app packaged as WAR. The only question is why?


      3. Well, those services are running on Spring Boot. Tomcat is embedded and is starting with application: java -jar Application. Port can be overriden with VM argument -DPORT. If you would like to deploy it on external Tomcat you have to remove Spring Boot and use stardard Spring Web app packaged as WAR. The only question is why? These are microservices


      4. Thanks for your reply.
        The reason behind to deploy to external server is, all applications are at same place and easy to debug through tomcat log files and easy to restart the server.
        If I ran these services from command prompt, is it possible ?
        I don’t have knowledge on spring boot. Trying to understand it. Hope you understand my concerns.


      5. So you mean to say, I should run all services from command prompt. Right ?
        If I run from command prompt, by any chance do I need to restart the server anytime ?


      6. Thanks for your quick responses.
        To execute all micro services (jar files) at once, which is the best method ?
        I mean Batch script is better or any other ?


    1. if you are using IDE like Eclipse or IntelliJ just run main class, for example pl.piomin.microservices.account.Application for account-service. You can also build your application with maven and that run using java -jar…


  2. Hi Piotr,
    Thanks for the tutorial. I tried creating two instances of account-service using the command: “java -jar target/account-service.jar -Dserver.port=2223” . But, am getting the below exception: “ Address already in use”. hwy it is not taking 2223 port. Please help.


      1. Hi Piotr,
        I tried the way you have suggested. “java -jar target/account-service.jar -DPORT=2223”. Still am getting the BindException. I could see the below line in the log: Tomcat initialized with port(s): 2222 (http)


  3. Hi Piotr,

    I have a doubt. Is it possible to balance the load among the different instances of a microservice. Say for example, can we limit the number of requests to be processed by an instance should be 50 and the rest has to be processed by another instance.
    Do we require any configuration changes related to ribbon. Please help.


    1. Hi,
      Yes, it is possible. If you have more than instance registered in discovery server it is automatically load balanced by Zuul and by your microservice if you use Feign client or @LoadBalanced with Srpign RestTemplate


  4. I am glad you came up with this post! I was looking for ways to build microservices using Zuul and this has helped me a lot. Expecting new posts from you on other microservice development aspects.


  5. Hi Piotr! I am wondering how to organize the customer-service, discovery-service, gateway-service, zipkin-service into Sample-spring-microservices project ? thanks much!!!!!!


Leave a Reply

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

You are commenting using your 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 )

Google+ photo

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

Connecting to %s