Application Tracing Using Spring Cloud Sleuth and Zipkin

One of the problems developers encounter as their microservice apps grow is tracing requests that propagate from one microservice to the next

Spring Cloud Sleuth is help with this exact problem. It introduces unique IDs to your logging which are consistent between microservice calls which makes it possible to find how a single request travels from one microservice to the next.

Spring Cloud Sleuth adds two types of IDs to your logging, one called a trace ID and the other called a span ID. The span ID represents a basic unit of work, for example sending an HTTP request. The trace ID contains a set of span IDs, forming a tree-like structure. The trace ID will remain the same as one microservice calls the next. span ID difference from one microservice to next.

Spring Cloud Sleuth will send tracing information(all the microservice log) to Zipkin server.  Using Zipkin UI  visualize the how many traced requests went through each application. you can filter or sort all traces based on the application, length of trace, annotation, or timestamp. Once you select a trace, you can see the percentage of the total trace time each span takes which allows you to identify the problem application.

Setting up the Zipkin Server in Spring Boot

  • add these dependencies to pom.xml
-----
<dependency>
 <groupId>io.zipkin.java</groupId>
 <artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
 <groupId>io.zipkin.java</groupId>
 <artifactId>zipkin-autoconfigure-ui</artifactId>
 <scope>runtime</scope>
</dependency>
--------
  • annotate the monitoring application with @EnableZuulServer (e.g. in ZipkinServerApplication.java)
  • Configuring log bean in the All micro service client application
#Add dependency
<dependency>    
<groupId>org.springframework.cloud</groupId>    
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
--------------------
#log format
@Bean
public AlwaysSampler defaultSampler() {   
 return new AlwaysSampler();
}

On pointing your browser to http://localhost:9411, you will see the all the http request trace information.

 

Avoiding cascading failures with circuit breaker

In the worst case your application will become unavailable as well: The screens of your application will freeze and not respond as the external system doesn’t return with a response. These problems are not new. Netflix made their solution using Hystrix

To deliver the above, Hystrix has built in the following defaults:

  1. Timeout for every request to an external system (default: 1000 ms)
  2. Limit of concurrent requests for external system (default: 10)
  3. Circuit breaker to avoid further requests (default: when more than 50% of all requests fail)
  4. Retry of a single request after circuit breaker has triggered (default: every 5 seconds)

For more details please have a look at http://hystrix.github.com. The wiki gives detailed information how to use it and the mechanisms inside.

Setting up the Hystrix in Spring Boot

  • annotate the main application with @EnableHystrix and @EnableCircuitBreaker (e.g. in ProductApplication.java)
  • API Method Enable circuit breaker with Hystrix Command.
@HystrixCommand(fallbackMethod = "fallbackGetProduct")
@RequestMapping(method=RequestMethod.GET) 
public List<Product> getProducts(){ 
return productJPARepo.findAll(); 
}

#fallback method return empty list
public List<Product> fallbackGetProduct() {
return new ArrayList<Product>(); 
}
  • Enable the Hystrix Dashboard annotate with @EnableHystrixDashboard.

On pointing your browser to http://application-host/hystrix.stream

Hystrix

The source code can be found here.

  • Closed: The circuit-breaker executes operations as usual. If a failure occurs, the circuit-breaker writes it down and if a specified error threshold (number of failures or frequency of failures) is reached, it trips and opens the circuit (transitions to the open-state).
  • Open: Calls to the circuit-breaker in the open state fail immediately without even trying to call the underlying operation. After a specified timeout is reached, the circuit-breaker transitions to the half-open state.
  • Half-open: In this state, one call is allowed to call the underlying operation. If this call fails, the circuit-breaker transitions to the open-state again until another timeout is reached, if it succeeds, the circuit-breaker resets and transitions to the closed-state.

RESTful API Documentation With Swagger 2

In this post, I’ll cover how to use Swagger 2 to generate REST API documentation for a Spring Boot project.

Setting up the Swagger 2 in Spring Boot

1.we need the following dependency declaration in our Maven POM.

-----
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>    
<version>2.6.1</version> 
</dependency> 
<dependency> 
   
<groupId>io.springfox</groupId>    
<artifactId>springfox-swagger-ui</artifactId>    
<version>2.6.1</version> 
</dependency>
--------

2.Rest Controller we need implements a set of Swagger 2 REST Endpoint specification.

# customize your resr api documents 
@ApiOperation( value = "List all Product", notes = "Returns a complete list of Product Details") 
@ApiResponses(value = { @ApiResponse(code = 200, message = "Successful retrieval of All Product details" )}) 
@RequestMapping(method=RequestMethod.GET) 
public List<Product> getProducts(){ 
return productJPARepo.findAll(); 
}

3.Configuring Swagger 2 in the Application

# we will create a Docket bean in a Spring Boot configuration to configure Swagger 2 for the application
@Configuration
@EnableSwagger2
public class SwaggerConfig {
       @Bean
       public Docket productApi() {
          return new Docket(DocumentationType.SWAGGER_2)
          .select() .apis(RequestHandlerSelectors.basePackage("com.accenture.api"))
          .paths(PathSelectors.any())
          .build();
      }
}

On pointing your browser to http://localhost:8080/swagger-ui.html, you will see the generated documentation rendered by Swagger UI, like this:

swagger.png

The source code can be found here

4. Centralized Custom API Information in API Gateway.

In API Gateway application follow the above 3 steps to configure the swagger 2 in our project. if You want to centralized all our micro service rest api document in one place we need to add all the micro service end point into  Swagger Resource Provider.

The source code can be found here

 

Implementing Spring Cloud Config

Spring Cloud Config  provides a way to make this easier Changing configurations on running services with out restart the service. Spring config server is centralized configuration. All the client service(Resource Service)  fetch their configuration information from config server.

 

config-server

 

Setting up the server and Client

The easies way is to create it from Spring Initializr with “Config Server”.

To set up the server you must:

  • annotate the main application with @EnableConfigServer (e.g. in ConfigserverApplication.java)
  • add the Git repository uri in the property spring.cloud.config.server.git.uri

The config-server source code can be found here.

Client side you should add only the config uri in resource property  spring.cloud.config.uri : {Config serve Running IP or Hostname}

By default, the configuration values are read on the client’s startup, and not again. You can pull updated values from the Config Server. You can invoke the refresh Spring Boot  Actuator endpoint by sending an empty HTTP POST to the client’s refresh endpoint, http://client-endpoint/refresh. Automate all the process using Spring Cloud Bus & Github webhook 

 

 

 

Microservices: Zero Downtime Deployment

How can we deliver business value faster?

Releasing software frequently to users is usually a time-consuming and painful process. Continuous Integration and Continuous Deployment (CI/CD) can help organizations to become more automating and streamlining the steps are involved.

Following tools to set up a CI/CD infrastructure

  • GitHub: Version control repository
  • Jenkins: CI/CD engine
  • Nexus Repository: build artifacts repository for managing JAR, WAR and EAR files
  • SonarQube: static code analysis to detect bugs and anti-patterns
  • Docker & Kubernetes : Containerization Platforms

The following diagram shows the example pipeline when every check-in (commit) the code into repository.

CI.png

 

Micro Services Deployment options and Virtualization

The best way to deploy Micro Services-based applications is inside Docker containers

  • packaging for a Linux process
    • immutable images
    • run everywhere
    • images are small and easy to cache
  • isolate processes
    • each container has its own file system and ports
    • set limits: IO, CPU, memory, …
    • run 1000s of containers per node rather than 10s of VMs.
  • Build, Ship, and Run distributed applications, whether on laptops, data center VMs, or the cloud etc..
  • Package Once Deploy Anywhere (PODA).

Kubernetes : 

  • Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications containers across clusters of hosts.
  • It was originally designed by Google. It has many features which are especially useful for applications running in production and providing container-centric infrastructure (like AWS)

Basic unit in Kubernetes:

Pod – This is the basic unit in Kubernetes. It can consist of one or more containers that are guaranteed to be co-located on the host machine and share the same resources. All containers deployed inside pod can see other containers via localhost. Each pod has a unique IP address within the cluster

Service – This is a set of pods that work together. By default, a service is exposed inside a cluster but it can also be exposed onto an external  IP address outside your cluster. We can expose it using one of four available behaviors: ClusterIP, NodePort, LoadBalancer and ExternalName.

Replication Controller – This is a specific type of Kubernetes controller. It handles replication and scaling by running a specified number of copies of a pod across the cluster. It is also responsible for pod replacement if the underlying node fails.

The following diagram shows the example of distributed application cloud infrastructure

Full setup

What about my favourite Microservices platform:

I like the developer experience offered by the Spring framework provides the application integration and packaging. Docker and Kubernetes provides the deployment and Scheduling, I also like Apache Camel (rather that Spring Integration in this case).

My Favourite Microservices Stack

My Favourite Microservices Java Full Stack Technology

Micro Service biggest Challenging is Operational complexity and Infrastructure. In Enterprise distribute application  N number of micro service are running in cloud infrastructure and services is more cost. Any of the product before going to production we need to test the application in different stage of environment.

Both OpenStack and OpenShift Origin are open source projects, and both provide cloud computing foundations. OpenStack provides “Infrastructure-as-a-Service”, or “IaaS” and OpenShift Origin provides “Platform-as-a-Service” or “PaaS”.

 

Monolithic Vs Microservice Architecture

Monolithic Architecture

Technical Definition

“Monolithic application has single code base with multiple modules. Modules are divided as either for business features or technical features. It has single build system which build entire application and/or dependency. It also has single executable or deployable binary” –

Monolithic Application Architecture

Benefits

  • Simple mental model for developers, One unit of access for coding, building, deploying and technology stack.
  • Simple scaling model for operations, just run multiple copies behind a load balancer

Difficulties with monolithic application, when it grow

  • Large monolithic code base makes complicated to understand, especially for new developer
  • Overloaded IDE, Large code base makes IDE slow, build time increase.
  • Scaling become challenging, It doesn’t scale with the data volume out-of-the-box
  • Continuously integration / deployment become complex and time-consuming.
  • Deployment frequency is limited,
  • Re-deploying means halting the whole system
  • Re-deployments will fail and increase the perceived risk of deployment
  • Extremely difficult to change technology or language or framework because everything is tightly coupled and depend up on each other.

Why Microservices?

  • Relatively small, easy to understand and maintain
  • Can be deployed, scaled independently of other microservices
  • Rollback is easy, wont bring down everything.
  • Dev teams can be small and productive, can be using different technologies

 

Micro Service Architecture

The Micro Service architectural approach to developing a single application as a small services, each services running in its own process and communicating with lightweight REST API Endpoint which may be written in different programming languages and use different data storage technologies.

These services are built around business capabilities and easier to apply Continuous Integration / Continuous Deployment by fully automated machinery

Micro Service architectures are defined by a Martin Fowler ,

functional system decomposition into manageable and independently deployable components

My point of view,

“ Micro Services is the architectural evolution of SOA, driven by DevOps practices ”

SOA systems also focus on functional decomposition, Services are not required to be self-contained deployable unit.

Microservice

 

Privilege with Micro Service architecture, when it grow

  • Each Micro Service is small and focused on a specific feature / business requirement
  • Micro Service can be developed independently by small team of developers (normally 5 to 9 developers).
  • Codebase is maintainable for developers – it fits into their brain
  • Tools work fast – building, testing, refactoring code takes seconds
  • Service startup only takes seconds
  • Micro Service is loosely coupled, means services are independent, in terms of development and deployment both.
  • Micro Service can be developed using different programming language.

Drawbacks / Issues ( Challenging…)

  • Micro Service is not ultimate solution for every application but it’s surely solution for large enterprise application.
  • Automated Testing complex because of distributed system testing is more difficult.
  • Multiple services requires careful coordination between the teams
  • Complex to tracking distributed system for centralized logging, Metrics, Health check, Audit, Exception and security become challenging.
  • Each service has its own database. Maintaining data consistency between services is a challenge because 2 phase-commit/distributed transactions is not an option for many applications
  • operational complexity of deploying and managing of many different micro service, Scaling application instances with NxM services instances

Micro Services Scaling Cube

The traditional method of scaling is running multiple copies of an application instances into load-balanced across servers is the X-axis.

scale-cube

The general approach of Micro Services falls along the Y-axis. Y-axis scaling breaks the application into its functional decomposition service.

The Z-axis takes a similar approach to the X-axis—running identical copies of code across multiple servers.

Z-axis scaling approach is based on routing criteria. You might route requests based on the primary key of the data being accessed or based on customer type sending paying or premium customers to servers with more bandwidth and capacity to deliver better performance.

In Monolithic Architectural Y axis scaling is out of box, monolithic you scale the complete “Application” even if it’s not required of specific module withing the application.

Advantage of Micro Service easier to scale the specific services of your application when ever needed.

 

Micro Services Concerns

 

Microservices Concerns

In the diagram above, we can see a list with the most common challenges on Micro Service concerns.

To address many of these new challenges will achieve using Java spring framework  with Spring Cloud and Netflix OSS libraries provides tools for Java developers to quickly build some of the common patterns in distributed systems such as configuration management (Spring Cloud Config) , service discovery (Netflix Eureka) ,  Ribbon (for load balancing), Service Security (Spring Cloud OAuth2) , Hystrix (fault tolerant and circuit breaker patterns), ELK-stack (Elasticsearch, Logstash and Kibana) for tracing libraries, etc.  We will see the details in  Next blog post.

MicroService using Spring Cloud and Netflix OSS

 

In the previous blog post we defined the overall micro service concerns.

This blog series we will see the what are operations models or components using spring framework with some  supporting services from Spring Cloud, Netflix OSS, etc.. to fix the Micro Service concerns. The source code is available on GitHub

The below table Maps the java technology to identify most common challenges on Micro Service operations model.

mapping-table.png

A SYSTEM LANDSCAPE

This diagram covers the run time aspects of the system, but doesn’t touch on the packaging, continuous integration, scaling, high availability, self healing side which are also very important in the MSA world. Click the link Zero Downtime Deployment

MSA

 

Config Service:  Spring Cloud Config is centralized configuration server for distributed systems. It uses a pluggable repository layer that currently supports local storage, Git, and Subversion. Spring Cloud Config provides a way to Changing configurations on running services with out restart the service.

Service Discovery: Netflix Eureka allows micro services (Client) to register themselves at run time as they appear in the system landscape. A service registry is useful because it enables client-side load-balancing.

To set up the server you must:

  • annotate the registry application with @EnableEurekaServer (e.g. in RegistryApplication.java)
  • annotate the Client application with @EnableDiscoveryClient.
  • Test the end-to-end result by starting the eureka-service first and then, once loaded, starting the eureka-client. The eureka-client will take about a minute to register itself in the registry
  • Service Registry contain the eureka-client IP address with port or host name

In the service discovery web app we should now be able to see our three business services and the API Gateway server (http://localhost:8761):

registry

 

API Gate Way: Netflix Zuul  is (of course) our gatekeeper to the outside world, not allowing any unauthorized external requests pass through. Zulu also provides a well known entry point to the micro services in the system landscape

Netflix Ribbon is Dynamic Routing and Load Balancing can be used by service consumers to lookup services at run time. Eureka registry to locate appropriate service instances. If more than one instance is found, Ribbon will apply load balancing to spread the requests over the available instances. Ribbon does not run as a separate service but instead as an embedded component in each service consumer.

Swagger REST APIREST APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined via Swagger, a consumer can understand and interact with the remote service with a minimal amount of implementation logic

Monitor Dashboard: Circuit breaker Netflix Hystrix provides circuit breaker capabilities to a service consumer. If a service doesn’t respond (e.g. due to a timeout or a communication error), Hystrix can redirect the call to an internal fallback method in the service consumer. If a service repeatedly fails to respond, Hystrix will open the circuit and call on every subsequent (HTTP) fallback method until the service is available again. Hystrix dashboard can be used to provide a graphical overview of all circuit breakers in a system landscape.

Centralized log analysis: To be able to track messages and detect when they got stuck we need a centralized log analysis function that is capable to reaching out to the servers and collect the log-files that each micro service produce. The log analysis function stores this log information in a central database and provide search and dashboard capabilities.

OAuth2 Security:  Spring Security OAuth2 we can quickly create systems that implement common patterns like single sign on, token relay and token exchange between resource servers. Using interceptor to make a Feign client behave like OAuth2RestTemplate (fetching tokens etc.)