logo

Tracing REST Services with Zipkin

Published on
Authors

Whether you deploy to the cloud or on-prem, one of the biggest challenges of a microservice or distributed architecture is monitoring.

Zipkin is a distributed tracing system that can help to solve some of these problems. Specifically, it helps gather data needed to troubleshoot latency issues.

In this article, we look at spring clouds support for Zipkin by setting up some spring boot REST services.

The example code is written in kotlin but can easily be ported over to java.


Source code for this example can be found on github:

tutorials/kotlin/spring-cloud-zipkin at main · mwhyte-dev/tutorials


Prerequisites

You’ll need some things to follow along with the example:

  • Java
  • Gradle
  • Docker (including docker-compose)
  • The source code is cloned and imported into your IDE

Setting the scene

To demonstrate Zipkin’s tracing abilities, we are going to bring up some fictitious services that our service can make requests to.

Our service will return the tax of an employee based on their name:

$ curl http://localhost:8080/tax\?name\=michael
$ 10000.0

To do this, it needs some help for other services:

  • An employee service which will return employee information by name
  • A payroll service that will return the employees tax code by employee id.

Finally, our service will calculate and return the tax to be paid.

Additionally, we will bring up a Zipkin server to which our service will push trace data.

The employee and payroll service will be mocked out using mockserver. We will not be covering mockserver in this post.

There are two JSON files under the dist directory that tell the mock services how to respond to requests, including some delays which will slow down their response times.


Compose

To manage all this, we will be using a docker-compose yml file:

version: '2.0'
services:
  zipkin:
    container_name: zipkin
    image: openzipkin/zipkin
    ports:
      - 8081:9411

  employee-service:
    container_name: employee-service
    image: mockserver/mockserver
    ports:
      - 8082:1080
    environment:
      MOCKSERVER_INITIALIZATION_JSON_PATH: /config/initializerJson.json
    volumes:
      - ./dist/employee-service:/config

  payroll-service:
    container_name: payroll-service
    image: mockserver/mockserver
    ports:
      - 8083:1080
    environment:
      MOCKSERVER_INITIALIZATION_JSON_PATH: /config/initializerJson.json
    volumes:
      - ./dist/payroll-service:/config

Let’s start everything up now by running:

docker-compose -f docker-compose.yml up

N.B. you can optionally background the process by adding -d to the end of this command


Creating a Basic Rest Service

Creating the service is very simple, and if you’re happy with spring boots defaults, then this only involves adding a jar to your maven pom or gradle file!

implementation("org.springframework.cloud:spring-cloud-starter-zipkin")
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifact>
    <version>2.2.0.RC1</version>
</dependency>

Default properties such as Zipkin URLs can be overridden under src/main/resources/application.properties

A full list of properties is listed in the spring cloud documentation

Hitting the endpoint

Start the service in your IDE and navigate to it in your browser:

Now navigate to the Zipkin UI. Click on Find Traces and you will see the trace you created by opening the service URL.

zipkin UI

Click on a span to expand it:


Apache Benchmark

Additionally, you could use a tool like Apache benchmark to put the service under some load. This will create more traces that can be viewed in the Zipkin UI:

ab -n 500 -c 20 "http://localhost:8080/tax?name=michael"

Conclusion

We've seen just how easy it is to add tracing to your spring cloud application.

For more info, see the spring cloud docs or the openzipkin examples on Github.