5
5
-----------------------------------------------------------------------------------
The API Gateway is a server. It is a single entry point into a system. API Gateway
encapsulates the internal system architecture. It provides an API that is tailored
to each client. It also has other responsibilities such as authentication,
monitoring, load balancing, caching, request shaping and management, and static
response handling.
API Gateway is also responsible for request routing, composition, and protocol
translation. All the requests made by the client go through the API Gateway. After
that, the API Gateway routes requests to the appropriate microservice.
The API Gateway handles the request in one of the two ways:
The popular example of API Gateway is Netflix API Gateway. The Netflix streaming
services are available on hundreds of different kinds of devices such as
televisions, set-top boxes, smartphones, tablets, etc. It attempts to provide a
one-size-fits-all API for its streaming service.
Security
Caching
API composition and processing
Managing access quotas
API health monitoring
Versioning
Routing
Disadvantages
It requires routing rules.
There is a possibility of a single point of failure.
Risk of complexity due to all the API rules are in one place.
Consider a scenario in which we do not want to call a microservice more than five
times by a particular client. We can do it as a part of the limit in the API
Gateway. We can implement the common features across microservices in the API
gateway. The Zuul API Gateway is a popular API Gateway implementation.
Service Aggregation
Authentication, authorization and Security
Rate Limits
Fault Tolerance
Suppose there is an external consumer who wants to call fifteen different services
as part of one process. It is better to aggregate those fifteen services and
provide one service call for the external consumer. These are the kinds of features
that are common across all the microservices. These features are implemented at the
level of API.
Instead of allowing microservices to call each other directly, we would do all the
calls through API Gateway. API Gateway will take care of common features like
authentication, fault tolerance, etc. It also provides aggregation services around
all microservices because all calls get routed through the API Gateway.
In this section, we will implement the logging functionality in the Zuul API
Gateway.
shouldFilter(): The shouldFilter() method checks the request and decides whether
filter to be executed or not.
run(): The run() method invokes, if both !isFilterDisabled() and shouldFilter()
methods returns true.
filterType(): The filterType() method classify a filter by type. There are four
types of standard filters in Zuul: pre for pre-routing filtering, route for routing
to an origin, post for post-routing filters, and error for error handling. Zuul
also supports a static type for static responses. Any filter type can be created or
added and run by calling the method runFilters(type).
filterOrder(): The filter order must be defined for a filter. Filters may have the
same filter order if the precedence is not important for the filters. The filter
order does not need to be sequential.
Step 5: Create the Logger class object and invoke getLogger() method to create a
logger.
package com.javatpoint.microservices.netflixzuulapigatewayserver;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
@Component
public class ZuulLoggingFilter extends ZuulFilter
{
//creating Logger object
private Logger logger=LoggerFactory.getLogger(this.getClass());
@Override
public booleanshouldFilter()
{
return true; //executing filter for every request
}
//log the content of the request
@Override
public Object run() throws ZuulException
{
//getting the current HTTP request that is to be handle
HttpServletRequest request=RequestContext.getCurrentContext().getRequest();
//prints the detail of the requestin the log
logger.info("request -> {} request uri-> {}", request, request.getRequestURI());
return null;
}
@Override
public String filterType()
{
return "pre"; //intercept all the request before execution
}
@Override
public intfilterOrder()
{
return 1; //setting filter order to 1
}
}
-----------------------------------------------------------------------------------
-------
Executing a Request through Zuul API Gateway
-----------------------------------------------------------------------------------
-------
Step 5: Open the browser and invoke the URL http://localhost:8761. It shows all the
services that are registered with the Eureka naming server.
Let's invoke the request through the Zuul API Gateway. We use the following URL:
http://localhost:8765/{application-name}/{uri}. The port 8765 is the default port
for the Zuul API Gateway server.
http://localhost:8765/currency-exchange-service/currency-exchange/from/EUR/to/INR
Step 7: Copy the above URL and paste it in the browser. We get the same response as
above, but at this time, the request is going through the Zuul API Gateway.
We can also see the content of the request that is printed on the Zuul API Gateway
server. The request prints the request URI.
We have sent the request through the Zuul API Gateway, instead of directly calling
the microservices.
Step 7: Click on the arrow that is beside the console icon and select the
NetflixZullApiGatewayServerApplication.
Now let's intercept the calls between currency converter-service and currency-
exchange-service. It means the API Gateway executes two times when we invoke the
URL.
The first time, API Gateway executes when we call the currency-conversion-service.
It means before the execution of the currency-conversion-service. The currency-
conversion-service routed through the API Gateway.
The second time, API Gateway executes when the currency-conversion-service calls
the currency-exchange-service. It means after the execution of currency-conversion-
service and before the execution of currency-exchange-service. The currency-
exchange-service also routed through the API Gateway.
Send the request http://localhost:8765 through the API Gateway. The URI will be
/{application-name}/{uri}. The complete URL will look like the following:
http://localhost:8765/currency-conversion-service/currency-converter-feign/from/
USD/to/INR/quantity/1000
In this section, we have executed both the services through the Zuul API Gateway
server.
-----------------------------------------------------------------------------------
--
Introduction to Distributed Tracing
-----------------------------------------------------------------------------------
----
Distribute tracing provides a place where we can see that "what is happening with a
specific request?" It is important because there are a variety of components that
are involved in the microservices.
In this section, we will use Spring Cloud Sleuth with Zipkin. Spring Cloud Sleuth
assigns a unique Id to each request that we have made. We can trace all the
requests based on unique Ids across all the components.
Spring Cloud Sleuth is a Spring Cloud library that provides the ability to track
the progress of subsequent microservices by adding trace and span Ids on the
appropriate HTTP request headers. The Sleuth library is based on the MDC (Mapped
Diagnostic Context) concept, where we can easily extract values, put to context,
and display them in the log.
Zipkin
With the help of the Zipkin server, we can put all the logs of all the components
in the MQ (RabbitMQ). We send the logs to the Zipkin server where the logs
consolidate. After doing this, we can monitor different requests. We can also find
what is happening to a specific request?
In this step, we will add Spring Cloud Sleuth for all the microservices. It adds a
unique Id to all the requests. It is used to generate and attach the trace Id, span
Id to the logs so that tools (Zipkin) can use these ids.
Application name: The name of the application that is defined in the properties
file.
Trace Id: The Sleuth adds the Trace Id. It remains the same in all services for a
given request.
Span Id: The Sleuth also adds the Span Id. It remains the same in a unit of work
but different for different services for a given request.
Zipkin Export Flag: It indicates a boolean value. It can be either true or
The following figure shows the Spring Cloud Sleuth token.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
Now we need to trace all the requests. If we want to trace all the requests, we
would need to create ALWAYS_SAMPLE. We can create a Sampler by using a Bean.
When we export span data to the Zipkin or Spring Cloud Stream, Spring Cloud Sleuth
provides AlwaysSampler class that exports everything to the Zipkin. It also
provides a PercentageBasedSampler class that samples a fixed fraction of span.
Remember: If you are using Spring 2.0.0 or above versions, use the following
Sampler. We have used the same because we are using Spring version 2.2.1.
Remember: If you are using Spring 2.0.0 or above versions, use the following
Sampler. We have used the same because we are using Spring version 2.2.1.
@Bean
public Sampler defaultSampler()
{
return Sampler.ALWAYS_SAMPLE;
}
Step 3: Open NetflixZuulApiGatewayServerApplication.java file and define a Bean
package com.javatpoint.microservices.netflixzuulapigatewayserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import brave.sampler.Sampler;
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class NetflixZuulApiGatewayServerApplication
{
public static void main(String[] args)
{
SpringApplication.run(NetflixZuulApiGatewayServerApplication.class, args);
}
//creating a bean
@Bean
//creating a sampler called
public Sampler defaultSampler()
{
return Sampler.ALWAYS_SAMPLE;
}
}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
CurrencyExchangeServiceApplication.java
package com.javatpoint.microservices.currencyexchangeservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import brave.sampler.Sampler;
@SpringBootApplication
@EnableDiscoveryClient
public class CurrencyExchangeServiceApplication
{
public static void main(String[] args)
{
SpringApplication.run(CurrencyExchangeServiceApplication.class, args);
}
@Bean
//creating a sampler called always sampler
public Sampler defaultSampler()
{
return Sampler.ALWAYS_SAMPLE;
}
}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
CurrencyConversionServiceApplication.java
package com.javatpoint.microservices.currencyconversionservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import brave.sampler.Sampler;
@SpringBootApplication
@EnableFeignClients("com.javatpoint.microservices.currencyconversionservice")
@EnableDiscoveryClient
public class CurrencyConversionServiceApplication
{
public static void main(String[] args)
{
SpringApplication.run(CurrencyConversionServiceApplication.class, args);
}
@Bean
//creating a sampler called always sampler
public Sampler defaultSampler()
{
return Sampler.ALWAYS_SAMPLE;
}
}
Now we have three applications that are connect to Spring Cloud Sleuth.
netflix-eureka-naming-server
Open the browser and invoke the URL http://localhost:8761. It returns the Eureka
interface, as shown below.
currency-exchange-service (on port 8000)
currency-conversion-service
netflix-zuul-api-gateway-server
It shows all the instances currently registered with the Eureka server.
package com.javatpoint.microservices.currencyexchangeservice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class CurrencyExchangeController
{
private Logger logger=LoggerFactory.getLogger(this.getClass());
@Autowired
private Environment environment;
@Autowired
private ExchangeValueRepository repository;
@GetMapping("/currency-exchange/from/{from}/to/{to}") //where {from} and {to}
are path variable
public ExchangeValue retrieveExchangeValue(@PathVariable String from, @PathVariable
String to) //from map to USD and to map to INR
{
ExchangeValue exchangeValue = repository.findByFromAndTo(from, to);
//setting the port
exchangeValue.setPort(Integer.parseInt(environment.getProperty("local.server.port")
));
logger.info("{}", exchangeValue);
return exchangeValue;
}
}
Step 10: Open CurrencyConversionContoller.java file and add a logger into it.
package com.javatpoint.microservices.currencyconversionservice;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class CurrencyConversionController
{
private Logger logger=LoggerFactory.getLogger(this.getClass());
@Autowired
private CurrencyExchangeServiceProxy proxy;
@GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}") //where
{from} and {to} represents the column
//returns a bean back
public CurrencyConversionBean convertCurrency(@PathVariable String from,
@PathVariable String to, @PathVariable BigDecimal quantity)
{
//setting variables to currency exchange service
Map<String, String> uriVariables=new HashMap<>();
uriVariables.put("from", from);
uriVariables.put("to", to);
//calling the currency exchange service
ResponseEntity<CurrencyConversionBean> responseEntity=new
RestTemplate().getForEntity("http://localhost:8000/currency-exchange/from/{from}/
to/{to}", CurrencyConversionBean.class, uriVariables);
CurrencyConversionBean response=responseEntity.getBody();
//creating a new response bean and getting the response back and taking it into
Bean
return new CurrencyConversionBean(response.getId(), from, to,
response.getConversionMultiple(), quantity,
quantity.multiply(response.getConversionMultiple()), response.getPort());
}
//mapping for currency-converter-feign service
@GetMapping("/currency-converter-feign/from/{from}/to/{to}/quantity/
{quantity}") //where {from} and {to} represents the column
//returns a bean
public CurrencyConversionBean convertCurrencyFeign(@PathVariable String from,
@PathVariable String to, @PathVariable BigDecimal quantity)
{
CurrencyConversionBean response=proxy.retrieveExchangeValue(from, to);
logger.info("{}", response);
//creating a new response bean
//getting the response back and taking it into Bean
return new CurrencyConversionBean(response.getId(), from, to,
response.getConversionMultiple(), quantity,
quantity.multiply(response.getConversionMultiple()), response.getPort());
}
}
Spring Cloud Sleuth assigns a trace Id to the request. We can use this Id to trace
the requests across multiple components. But there is a problem that this log is
distributed in multiple places. We use Zipkin to remove this problem. With the help
of Zipkin, we can centralize the logs in one place.
We need to centralize all the logs from all the microservices. We can search
through Id assigned by Spring Cloud Sleuth. At the centralized place, we will able
to search and find out what is happening to a specific request.
There are the following solutions for centralize logging:
In this distributed tracing, we will use Zipkin distribute tracing server. It gives
us a consolidated view of all the microservices. We get all the logs messages form
the individual microservices. The Zipkin server collects the log messages. All the
microservices puts the log messages on the queue called RabbitMQ, and the Zipkin
picks these log messages from the RabbitMQ. The Zipkin tracing server is connected
with the database.
In our case, we use the in-memory database. We will pull log messages from the
database. In the next step, we will install RabbitMQ.
-----------------------------------------------------------------------------------
---
Installing RabbitMQ Server
-----------------------------------------------------------------------------------
---
RabbitMQ is widely deployed open-source message broker software that implements
Advanced Message Queuing Protocol (AQMP). It is lightweight and easy to deploy in
the cloud. It supports multiple messaging protocols. It can be deployed in a
distributed environment to meet high-scale and high-availability requirements. It
is modeled on the AMQP standard. The RabbitMQ is written in the Erlang programming
language. It is developed on the Open Telecom Platform (OTP) framework for
clustering and failover.
Advantagesof RabbitMQ
----------------------
Fast performance
Polyglot (using several languages)
Easy Management
No Erlang knowledge needed
Great documentation
AMQPdefines:
-----------
Where to send messages (Routing)
How to get there (Delivery)
What goes in must come out (Fidelity)
Message broker
A message broker sits between the machine and the distributed computing system.
Instead of passing the messages directly to the receiver, the messages are first
sent to the message broker (RabbitMQ). The message broker orders the messages in an
optimized queue and passes them to the receiving machine when the machines are
ready to process the messages.
The machine that sends the message is called the producer. The machine that
receives the message is called the consumer. The bit in the middle is called
thebroker.
Erlang
Erlang is a compiled, fault-tolerant, concurrent, dynamically typed programming
language. It is used to build a massively scalable, real-time system with
requirements on high availability. It is used in banking, e-commerce, telecom,
computer telephony, and instant messaging.
OTP
OTP stands for Open Telecom Platform. It is a collection of Erlang libraries and
design principles. It provides middleware to develop these systems. It includes its
own tools such as distributed database, applications to interface towards other
languages, debugging and release handling tools.
Step 3: Open the command prompt and run the following commands one by one:
c:\>cd\
c:\>cd Program Files
c:\Program Files>cd RabbitMQ Server
c:\Program Files\RabbitMQ Server>dir
c:\Program Files\RabbitMQ Server>cd rabbitmq_server-3.8.1
c:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.1>dir
c:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.1>cd sbin
c:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.1\sbin>dir
c:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.1\sbin>rabbitmq-plugins enable
rabbitmq_management
Step 4: Press the Windows key and type services or press Windows key+R and type
services.msc.
Step 7: Provide the Username and Password and click on Login button. The default
username and password is guest.
Search Zipkin quickstart on Google. Click on the link Quickstart OpenZipkin. We get
the two options to quick start Zipkin, one is Docker, and the other is Java. But we
will use the Java approach.
Step 3: Copy the JAR file and paste it into any folder or drive. We have pasted the
JAR file in the C drive directly.
Step 4: Open the Command Prompt and run the following commands:
Here, the most important thing is that the Zipkin server must listen over the
RabbitMQ server. So we have to start the RabbitMQ server in the background.
C:\>SET RABBIT_URI=amqp://localhost
C:\> java -jar zipkin-server-2.12.9-exec.jar
The commands again start the Zipkin server along with the RabbitMQ server.
In this section, we have installed the Zipkin server. We have also started the
RabbitMQ server and connect it to the Zipkin server. Now the Zipkin server is
listening over the RabbitMQ server. But the microservices are not putting the trace
messages in the RabbitMQ.
In the next step, we will start putting the trace messages in the RabbitMQ.
We want to create a message in the format that it excepts. We need to add Zipkin
dependency.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
We will send the message to Zipkin that uses amqp message protocol. So we need to
add the amqp dependency. Adding the dependency of amqp, we get the connection of
RabbitMQ into currency-conversion-service, currency-exchange-service, and the
netflix-zuul-api-gateway-server.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Step 1: Run the following services in the same order as we have listed.
NetflixEurekaNamingServerApplication.java
ZipkinDistributedTracingServerApplication (run from the Command Prompt)
CurrencyExchangeServiceApplication.java (on port 8000)
CurrencyConversionServiceApplication.java (on port 8100)
NetflixZuulApiGatewayServerApplication.java
Remember: Make sure that all the five applications are running correctly.
Step 3: Open the Zipkin UI. It shows all the three services that we have connected
to Zipkin.
Step 4: Select any one service from the dropdown list and click on the Find Traces
button. We have selected a currency-conversion-service. It shows the list of
different execution of currency-conversion-service.
In the above figure, when we invoke the currency-converter-feign, the request first
goes to the API Gateway, and the API Gateway sends the request to the currency-
exchange-service.
We can also see the detail of the services. In the following image, we have shown
the details of the currency-exchange-service.
{"maximum":222,"minimum":2}
Step 5: Open the browser and invoke the URL http://locahost:8081/limits. It returns
the same response as the original limits-service sends.
{"maximum":222,"minimum":2}
Step 9: Open the Postman and send a POST request with the URL
http://localhost:8080/application/refresh.
If you are invoking the URL http://localhost:8080/limits and it does not return
the new values. So to get the new values on invoking the URL
http://localhost:8081/limits, you have to do the following:
Open the Postman and send a POST request with the URL
http://localhost:8081/application/refresh.
We have created the two instances of the limits-service. Suppose there are a
hundred instances of the limits-services that are running in parallel. We need to
invoke a hundred URLs to refresh the configuration from the Git repository.
Whenever we make the changes in the configurations, it must reflect changes in the
microservices. Here, the Spring Cloud Bus provides the solution for this, so we do
not need to call hundred URLs.
Spring Cloud Bus provides a URL for all the hundred instances. When we invoke that
URL, all the instances of the microservices would be updated with the latest values
from the Git configuration.
-----------------------------------------------------------------------------------
----
Implementing Spring Cloud Bus
-----------------------------------------------------------------------------------
----
In this section, when we make the changes in the Git repository, we have to hit
multiple instances of the limits-service to refresh the configuration.
We will invoke one URL, and it will reflect all the hundred instances of the
microservices. Here we will use Spring Cloud Bus. There are many options available
in the Spring Cloud Bus: Apache Kafka, RabbitMQ, etc. In this section, we will use
RabbitMQ.
Note: Before moving to the next step, make sure that the RabbitMQ server is running
in the background.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Step 6: Open the limits-service-qa.properties file and change the minimum value
from 22 to 29.
Step 7: Open the Postman and send a POST request with the URL
http://localhost:8080/bus/refresh.
Note: If you are using Spring Boot 2.0.0 or above versions, use the following URL:
http://localhost:8080/actuatror/bus-refresh
We have seen that the minimum value changes to 29. Here, you can notice that we
have not committed the changes in the Git repository manually, but the changes
reflect in both instances of limits-service.
When we make changes in configuration, and the changes are called on any of the
instances, the microservice sends an event over the Spring Cloud Bus. The Spring
Cloud Bus propagates that event to all the microservice instances that are
registered with it.
In this section, we have solved the problem of calling multiple instances of
microservices.
-----------------------------------------------------------------------------------
-------
Fault Tolerance with Hystrix
-----------------------------------------------------------------------------------
--------
Fault Tolerance
---------------
Consider a scenario in which six microservices are communicating with each other.
The microservice-5 becomes down at some point, and all the other microservices are
directly or indirectly depend on it, so all other services also go down.
Fault tolerance can be achieved with the help of a circuit breaker. It is a pattern
that wraps requests to external services and detects when they fail. If a failure
is detected, the circuit breaker opens. All the subsequent requests immediately
return an error instead of making requests to the unhealthy service. It monitors
and detects the service which is down and misbehaves with other services. It
rejects calls until it becomes healthy again.
Hystrix
-------
Hystrix is a library that controls the interaction between microservices to provide
latency and fault tolerance. Additionally, it makes sense to modify the UI to let
the user know that something might not have worked as expected or would take more
time.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
LimitsServicesApplication.java
package com.javatpoint.microservices.limitsservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@SpringBootApplication
@EnableHystrix
public class LimitsServiceApplication
{
public static void main(String[] args)
{
SpringApplication.run(LimitsServiceApplication.class, args);
}
}
@GetMapping("/fault-tolerance-example")
//configuring a fallback method
@HystrixCommand(fallbackMethod="fallbackRetrieveConfigurations")
public LimitConfiguration retrieveConfigurations()
{
throw new RuntimeException("Not Available");
}
//defining the fallback method
public LimitConfiguration fallbackRetrieveConfigurations()
{
//returning the default configuration
return new LimitConfiguration(999, 9);
}
In the above method, we have created a Get mapping for fault tolerance. In the next
line, we have used an annotation @HystrixCommand to configure the fallback method.
We have defined a method with the name fallbackRetrieveConfigurations() that
returns the default value if any fault occurs.
Fallback method
-----------------
The fallback method is a method that invokes when a fault occurs. Hystrix allows us
to define a fallback method for each service method. Here one question arises that
if the method throws an exception, what should be returned to the consumer?