Home » Java » Enterprise Java » Learning Spring-Cloud – Writing a microservice

About Biju Kunjummen

Biju Kunjummen

Learning Spring-Cloud – Writing a microservice

Continuing my Spring-Cloud learning journey, earlier I had covered how to write the infrastructure components of a typical Spring-Cloud and Netflix OSS based micro-services environment – in this specific instance two critical components, Eureka to register and discover services and Spring Cloud Configuration to maintain a centralized repository of configuration for a service. Here I will be showing how I developed two dummy micro-services, one a simple “pong” service and a “ping” service which uses the “pong” service.


Sample-Pong microservice

The endpoint handling the “ping” requests is a typical Spring MVC based endpoint:

public class PongController {

    private String message;

    @RequestMapping(value = "/message", method = RequestMethod.POST)
    public Resource<MessageAcknowledgement> pongMessage(@RequestBody Message input) {
        return new Resource<>(
                new MessageAcknowledgement(input.getId(), input.getPayload(), message));


It gets a message and responds with an acknowledgement. Here the service utilizes the Configuration server in sourcing the “reply.message” property. So how does the “pong” service find the configuration server, there are potentially two ways – directly by specifying the location of the configuration server, or by finding the Configuration server via Eureka. I am used to an approach where Eureka is considered a source of truth, so in this spirit I am using Eureka to find the Configuration server. Spring Cloud makes this entire flow very simple, all it requires is a “bootstrap.yml” property file with entries along these lines:

    name: sample-pong
        enabled: true
        serviceId: SAMPLE-CONFIG

    nonSecurePort: ${server.port:8082}
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/

The location of Eureka is specified through the “eureka.client.serviceUrl” property and the “spring.cloud.config.discovery.enabled” is set to “true” to specify that the configuration server is discovered via the specified Eureka server.

Just a note, this means that the Eureka and the Configuration server have to be completely up before trying to bring up the actual services, they are the pre-requisites and the underlying assumption is that the Infrastructure components are available at the application boot time.

The Configuration server has the properties for the “sample-pong” service, this can be validated by using the Config-servers endpoint – http://localhost:8888/sample-pong/default, 8888 is the port where I had specified for the server endpoint, and should respond with a content along these lines:

"name": "sample-pong",
  "profiles": [
  "label": "master",
  "propertySources": [
      "name": "classpath:/config/sample-pong.yml",
      "source": {
        "reply.message": "Pong"

As can be seen the “reply.message” property from this central configuration server will be used by the pong service as the acknowledgement message

Now to set up this endpoint as a service, all that is required is a Spring-boot based entry point along these lines:

public class PongApplication {
    public static void main(String[] args) {
        SpringApplication.run(PongApplication.class, args);

and that completes the code for the “pong” service.

Sample-ping micro-service

So now onto a consumer of the “pong” micro-service, very imaginatively named the “ping” micro-service. Spring-Cloud and Netflix OSS offer a lot of options to invoke endpoints on Eureka registered services, to summarize the options that I had:

  1. Use raw Eureka DiscoveryClient to find the instances hosting a service and make calls using Spring’s RestTemplate.
  2. Use Ribbon, a client side load balancing solution which can use Eureka to find service instances
  3. Use Feign, which provides a declarative way to invoke a service call. It internally uses Ribbon.

I went with Feign. All that is required is an interface which shows the contract to invoke the service:

package org.bk.consumer.feign;

import org.bk.consumer.domain.Message;
import org.bk.consumer.domain.MessageAcknowledgement;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

public interface PongClient {

    @RequestMapping(method = RequestMethod.POST, value = "/message",
            produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    MessageAcknowledgement sendMessage(@RequestBody Message message);

The annotation @FeignClient(“samplepong”) internally points to a Ribbon “named” client called “samplepong”. This means that there has to be an entry in the property files for this named client, in my case I have these entries in my application.yml file:

    DeploymentContextBasedVipAddresses: sample-pong
    NIWSServerListClassName: com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
    ReadTimeout: 5000
    MaxAutoRetries: 2

The most important entry here is the “samplepong.ribbon.DeploymentContextBasedVipAddresses” which points to the “pong” services Eureka registration address using which the service instance will be discovered by Ribbon.

The rest of the application is a routine Spring Boot application. I have exposed this service call behind Hystrix which guards against service call failures and essentially wraps around this FeignClient:

package org.bk.consumer.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.bk.consumer.domain.Message;
import org.bk.consumer.domain.MessageAcknowledgement;
import org.bk.consumer.feign.PongClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

public class HystrixWrappedPongClient implements PongClient {

    private PongClient feignPongClient;

    @HystrixCommand(fallbackMethod = "fallBackCall")
    public MessageAcknowledgement sendMessage(Message message) {
        return this.feignPongClient.sendMessage(message);

    public MessageAcknowledgement fallBackCall(Message message) {
        MessageAcknowledgement fallback = new MessageAcknowledgement(message.getId(), message.getPayload(), "FAILED SERVICE CALL! - FALLING BACK");
        return fallback;

“Boot”ing up

I have dockerized my entire set-up, so the simplest way to start up the set of applications is to first build the docker images for all of the artifacts this way:

mvn clean package docker:build -DskipTests

and bring all of them up using the following command, the assumption being that both docker and docker-compose are available locally:

docker-compose up

Assuming everything comes up cleanly, Eureka should show all the registered services, at http://dockerhost:8761 url –


The UI of the ping application should be available at http://dockerhost:8080 url –


Additionally a Hystrix dashboard should be available to monitor the requests to the “pong” app at this url http://dockerhost:8989/hystrix/monitor?stream=http%3A%2F%2Fsampleping%3A8080%2Fhystrix.stream:



  1. The code is available at my github location – https://github.com/bijukunjummen/spring-cloud-ping-pong-sample
  2. Most of the code is heavily borrowed from the spring-cloud-samples repository – https://github.com/spring-cloud-samples
Reference: Learning Spring-Cloud – Writing a microservice from our JCG partner Biju Kunjummen at the all and sundry blog.
(0 rating, 0 votes)
You need to be a registered member to rate this.
1 Comment Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy
Notify of
The comment form collects your name, email and content to allow us keep track of the comments placed on the website. Please read and accept our website Terms and Privacy Policy to post a comment.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Newest Most Voted
Inline Feedbacks
View all comments
3 years ago

The gateway project included on github is starting up, but it does not route requests to services.

I did not see any mention about the gateway in the text, but should it be working or is more configuration needed?