API Gateway service Spring Cloud Zuul

The API Gateway is a more intelligent application server that exists as the face of the entire microservices architecture system, scheduling and filtering all external client access through it. In addition to the functions of request routing, load balancing and checksum filtering, it also needs to combine with the service governance framework, the circuit breaker mechanism of request forwarding, and a series of advanced functions of service aggregation.

Spring Cloud Zuul, an API gateway component based on the Netflix Zuul implementation, is provided in Spring Cloud. For the maintenance of routing rules and service instances, Spring Cloud Zuul registered itself as an application under Eureka governance by integrating with Spring Cloud Eureka, and obtained instance information of all other microservices from Eureka. This automates the maintenance of service instances to the service governance framework. Human intervention is no longer required. For the maintenance of routing rules, Zuul creates route mappings by default with the service name as the ContextPath. For the similar signature verification and login verification, a single service can exist independently, but it does not call each micro-service, but makes a unified call on the API gateway service to pre-filter the micro-service interface, and realizes the interception and verification of the micro-service interface. Spring Cloud Zuul provides a set of filter mechanisms that support such tasks well.

1. Fast integration with Spring Cloud Zuul

1.1 Gateway Construction

  1. Create a basic Spring Boot project

  2. Add dependencies: spring-cloud-starter-zuul

  3. EnableZuul’s API gateway service with the @enableZuulProxy annotation on the main class

  4. Configure basic Zuul application information

    spring.application.name=api-gateway
    spring.port=8080
    Copy the code

1.2 Request Route

Start the Eureka service registry and microservices application

  • Traditional routing

    Add a route configuration rule for the API-gateway service

    zuul.routes.api-a-url.path=/api-a-url/**
    zuul.routes.api-a-url.url=http://localhost:8081/
    Copy the code

    Define requests to the API gateway that all access that meets the/api-a-URL /** rule will be routed to the http://localhost:8081/ address. The apI-a-URL part is the route name, which can be defined arbitrarily. A set of route names in the mapping relationship between path and URL must be the same.

  • Service-oriented routing

    Spring Cloud Zuul’s seamless integration with Spring Cloud Eureka gives way to a path that maps not to a specific URL but to a specific service, which is automatically maintained by Eureka’s service discovery mechanism, called service-oriented routing.

    1. Add dependencies: spring-cloud-starter-Eureka

    2. Configure the location of the Eureka registry for Zuul

    3. Configuring Service Routing

      zuul.routes.api-a.path=/api-a/**
      zuul.routes.api-a.serviceId=hello-service
      Copy the code

      Compact configuration

      zuul.routes.hello-service=/api-a/**
      Copy the code

1.3 Request Filtering

Zuul allows the interception and filtering of requests by defining filters on the API gateway by inheriting the ZuulFilter abstract class and defining its four abstract functions.

public class AccessFilter extends ZuulFilter {
    /** * Filter type, which determines in which lifecycle of the request the filter is executed */
    @Override
    public String filterType(a) {
        return "pre";
    }
    
    /** * Filter execution order. If multiple filters exist in the same phase, specify the execution order according to the return value */
    @Override
    public int filterOrder(a) {
        return 0;
    }
    
    /** * Whether the filter executes */
    @Override
    public boolean shouldFilter(a) {
        return true;
    }
    
    /** * Filter task */
    @Override
    public Object run(a) {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        
        String token = request.getHeader("Authorization");
        
        if (token == null) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            // ctx.setResponseBody(body);
        }
        
        return null; }}Copy the code

Define Zuul interceptor configuration and add interceptors

@Configuration
public class ZuulFilterConfiguration {
    
    @Bean
    public AccessFilter accessFilter(a) {
        return newAccessFilter(); }}Copy the code

2. Route description

2.1 Service Route Configuration

Compact configuration

zuul.routes.hello-service=/api-a/**
Copy the code

2.2 Default Rules for Service Routing

When Spring Cloud Eureka is introduced into the API gateway service built for Spring Cloud Zuul, it automatically creates a default routing rule for each service in Eureka. The path of the default routing rule prefixes the request with the service name configured by serviceId. Take hello-service as an example:

zull.routes.hello-service.path=/hello-service/**
zull.routes.hello-service.serviceId=hello-service
Copy the code

2.3 Path Matching

In Spring Cloud Zuul, route matching path expressions are defined in the Ant style

The wildcard instructions
? Matches any single character
* Matches any number of characters
** Matches any number of characters and supports multi-level directories

2.4 Ignoring expressions

The Spring Cloud Zuul ignores the expression parameter zuul.ignore-Patterns is used to set URL expressions that do not want to be routed by the API gateway.

zuul.ignored-patterns=/**/hello/**
Copy the code

2.5 Cookies and Headers

By default, Spring Cloud Zuul filters out sensitive information in HTTP request headers when requesting routes, preventing it from being passed downstream to external servers. The default sensitiveheaders are defined by zuul.sensitiveheaders, including the Cookie, set-cookie, and Authorization attributes.

Solution:

  • Sets the global parameter to the null override default value

    zuul.sensitiveheaders=
    Copy the code
  • Sets the parameters of the specified route

    Zuul.routes.<router>. CustomSensitiveHeaders =true // Set the sensitiveHeaders of the specified route to null zuul.routes.<router>.sensitiveheaders=Copy the code

2.6 Hystrix and Ribbon support

Zuul itself includes modular dependencies on Hystrix and the Ribbon, so Zuul has thread isolation and self-protection for circuit breakers, as well as client-side load balancing for service calls. The preceding function is unavailable when the mapping between path and URL is used to configure routing rules. Therefore, use the combination of Path and serviceId when Zuul is used. Set the parameters as follows:

Ribbon: ReadTimeout: 600000 // Sets the timeout period for the route forwarding request. ConnectTimeout: 600000 // Sets the timeout period for the route forwarding requestCopy the code
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 60000 // Sets the timeout period for HystrixCommand execution of THE API gateway route forwarding requestCopy the code

2.7 Filter details

In Zuul, when the routing function is actually running, its route mapping and request forwarding is done by several different filters. Route mapping is implemented through pre filters. It matches the request path with the configured routing rule to find the route address to be forwarded. Part of the request forwarding is done by the Route class filter.

Filters implemented in Spring Cloud Zuul must contain four basic characteristics: filter type, order of execution, execution condition, and specific operation. They are, in effect, four abstract methods defined in the ZuulFilter interface:

String filterType(a);
int filterOrder(a);
boolean shouldFilter(a);
Object run(a);
Copy the code
  • FilterType: indicates the filterType
    • Pre: can be invoked before the request is routed
    • Routing: Called when routing a request
    • Post: called after routing and error filters
    • Error: Called when an error occurs while processing a request
  • FilterOrder: indicates the filter execution order. A smaller value indicates a higher priority
  • ShouldFilter: Whether to implement a filter
  • Run: indicates filtering logic

2.8 Exception Handling

In Spring Cloud Zuul, a number of core filters are implemented by default during each phase of the HTTP request life cycle, which are automatically loaded and enabled when the API gateway service is started. However, there is no filter for the error phase in the core filter, so we need to handle the exception content in the custom filter:

  • Try-catch processing

    Error has three main parameters:

    1. Error. status_code: indicates the error code
    2. Error. Exception: Exception exception object
    3. Error. Message: Error message (priority over message in the Exception object)
    public Object run(a) {
        RequestContext ctx = RequestContext.getCurrentContext();
        
        try {
            // TODO
        } catch (Exception exception) {
            ctx.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            ctx.set("error.exception", exception);
        }
        
        return null;
    }
    Copy the code
  • ErrorFilter processing

    When exceptions are thrown in the pre, Route and POST phases of the request life cycle, they are processed in the error phase, and the error type filter is created to capture and process the exception information.

    public Object run(a) {
        RequestContext ctx = RequestContext.getCurrentContext();
        Throwable throwable = ctx.getThrowable();
        
        ctx.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        ctx.set("error.exception", throwable.getCause());
        
        return null;
    }
    Copy the code