Spring Cloud Zuul

The development environment

  • The idea of 2019.1.2
  • Jdk1.8.0 _201
  • Spring Boot 2.1.9. RELEASE
  • Spring Cloud Greenwich SR3

Zuul introduction

Zuul is a gateway service developed by Netflix that provides dynamic routing, monitoring, flexibility, and security. It can be used with Eureka,Ribbon,Hystrix, and other components. Verification filtering can also be supported by creating filters to make microservice applications more focused on business logic development.

The advantage of using Zuul Gateway services is to provide REST apis to external systems in a unified way, with additional functions such as permission control, load balancing, and so on, that exist separately from the original services.

Zuul provides different types of filters for processing requests that allow us to do the following

  • Permission control and security: Identifies information needed for authentication and rejects requests that do not meet the criteria
  • Monitor: Monitors request information
  • Dynamic routing: Dynamically routes requests to different service clusters in the background as required
  • Stress test: Ramp up the traffic to the cluster for performance evaluation
  • Load balancing: Allocates capacity for each type of request and discards requests that exceed the quota
  • Current limiting
  • Blacklist and whitelist filtering
  • Static resource processing: Responses to static resources are handled directly in Zuul without the need to forward these requests to the internal cluster

The filter

ZuulFilter is a basic abstract class that defines some abstract methods

  • FilterType: filter type, including “pre”, “route”, “post”, “error”, “static”

    • Pre: executed before the request is routed
    • Route: Executed when the request is routed
    • Post: Executed after the request has been routed
    • Error: Executed when an error occurs in the request
    • Static: Special Filter see StaticResponseFilter, which allows the response to be generated from Zuul itself, rather than forwarding the request to the source
  • FilterOrder method: Priority, higher level, faster execution (lower value indicates higher level)

  • ShouldFilter method: switch, if true, the run method is executed, otherwise not

  • The run method: logical operation performed by filter

Code implementation

1. Create a service registry

Create zuul-Eureka-server project, introduce Eureka-server dependency, project complete source code can be viewed: Spring Cloud Zuul sample source code

Here are some key pieces of code

Pom adds dependencies

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
Copy the code

The @enableeurekaserver annotation is added to the startup class

@EnableEurekaServer
@SpringBootApplication
public class ZuulEurekaServerApplication {
    public static void main(String[] args) { SpringApplication.run(ZuulEurekaServerApplication.class, args); }}Copy the code

Yml configuration

server:
  port: 8761

spring:
  application:
    name: zuul-eureka-server

eureka:
  instance:
    hostname: localhost   # eureka instance name
  client:
    register-with-eureka: false # Do not register yourself with the registry
    fetch-registry: false       # Whether to retrieve services
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  Registry access address
Copy the code

2. Create service provider 1

Create zuul-server-provider project, introduce Eureka-client dependency, project complete source code can be viewed: Spring Cloud Zuul example source code

Here are some key pieces of code

Pom adds dependencies

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
Copy the code

Write the HelloController service

@RestController
@Slf4j
public class HelloController {

    @RequestMapping("/hello")
    public String index(@RequestParam String name) {
        log.info("request one name is " + name);
        return "hello " + name + "This is the first messge"; }}Copy the code

The startup class adds the @enableDiscoveryClient annotation

@SpringBootApplication
@EnableDiscoveryClient
public class ZuulServerProviderApplication {

    public static void main(String[] args) { SpringApplication.run(ZuulServerProviderApplication.class, args); }}Copy the code

Yml configuration

spring:
  application:
    name: zuul-server-provider
server:
  port: 9000
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
Copy the code

3. Create service provider 2

Create zuul-server-provider2 project, introduce eureka-client dependency, other same service provider 1 project, project complete source code can be seen: Spring Cloud Zuul sample source code

The difference code is posted below

Write the service, here to do service degradation test, set the current thread to a very long sleep time

@RestController
@Slf4j
public class HelloController {
    @RequestMapping("/hello")
    public String index(@RequestParam String name) {
        log.info("request two name is " + name);
        try{
            // To perform a service degradation test, set a very long sleep time, deliberately causing the service access to timeout
            Thread.sleep(1000000);  
        }catch ( Exception e){
            log.error(" hello two error",e);
        }
        return "hello " + name + ", this is two messge"; }}Copy the code

4. Create zuul service gateway

Create zuul-server-gateway project, introduce Netflix-Zuul and Eureka-client dependencies, project complete source code can be viewed: Spring Cloud Zuul example source code

Here are some key pieces of code

Pom. The XML configuration

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
Copy the code

Create a filter tokenfilter.java

package com.easy.zuulServerGateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;

@Slf4j
public class TokenFilter extends ZuulFilter {

    @Override
    public String filterType(a) {
        // Can be called before the request is routed
        return "pre";
    }

    @Override
    public int filterOrder(a) {
        //filter Execution sequence. The priority is 0. A larger number indicates a lower priority
        return 0;
    }

    @Override
    public boolean shouldFilter(a) {
        // Whether to run the filter. If the value is true, filtering is required
        return true;
    }

    @Override
    public Object run(a) {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        log.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());

        // Get the request parameters
        String token = request.getParameter("token");

        if (StringUtils.isNotBlank(token)) {
            // Route requests
            ctx.setSendZuulResponse(true);
            ctx.setResponseStatusCode(200);
            ctx.set("isSuccess".true);
            return null;
        } else {
            // Do not route it
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(400);
            ctx.setResponseBody("token is empty");
            ctx.set("isSuccess".false);
            return null; }}}Copy the code

Create a fuse corresponding to the Zuul-server-provider service (fusing for the entire service or for a single service interface), providerFallback.java

package com.easy.zuulServerGateway.fallback;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

@Slf4j
@Component
public class ProviderFallback implements FallbackProvider {

    @Override
    public String getRoute(a) {
        return "zuul-server-provider";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        if(cause ! =null) {
            String reason =cause.getMessage();
            log.info("Excption {}", reason);
        }
        return fallbackResponse();
    }

    public ClientHttpResponse fallbackResponse(a) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode(a) {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode(a) {
                return 200;
            }

            @Override
            public String getStatusText(a){
                return "OK";
            }

            @Override
            public void close(a) {}@Override
            public InputStream getBody(a) {
                return new ByteArrayInputStream("The service is unavailable.".getBytes());
            }

            @Override
            public HttpHeaders getHeaders(a) {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                returnheaders; }}; }}Copy the code

Yml configuration

spring:
  application:
    name: zuul-service-gateway
server:
  port: 8888

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

  # Whether to enable the retry function
zuul:
  retryable: true
  Number of retries for the current service
ribbon:
  MaxAutoRetries: 2
  # Number of times to switch the same Server
  MaxAutoRetriesNextServer: 0
Copy the code

Start the class add @ EnableZuulProxy annotations, to start the service gateway ZuulServerGatewayApplication. Java

package com.easy.zuulServerGateway;

import com.easy.zuulServerGateway.filter.TokenFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableZuulProxy
public class ZuulServerGatewayApplication {

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

    @Bean
    public TokenFilter tokenFilter(a) {
        return newTokenFilter(); }}Copy the code

First, the four services of the sample are created, and then run the sample to see the effect

use

The four existing projects are as follows

Zuul-eureka-server: service registry, service name: zuul-Eureka-server, port: 8761 Zuul-server-provider: service provider 1, service name: zuul-server-provider, port: 8761 9000 Zuul-server-provider2: indicates the service provider. Service name: indicates the zuul-server-provider. Port: indicates the 9001 zuul-server-gateway: indicates the service gateway. 8888

Run the test

Start zuul-Eureka-server, zuul-server-gateway, and zuul-server-provider respectively

  • Access the address: http://localhost:8888/zuul-server-provider/hello? Name =yuntian, return: token is empty, request intercepted return.
  • Access the address: http://localhost:8888/zuul-server-provider/hello? Name =yuntian&token=xx, return: hello yuntian, this is first messge, indicating a normal response to the request.

Start the zuul – server – provider2

  • Many times visit http://localhost:8888/zuul-server-provider/hello? Name =yuntian&token=xx
Hello yuntian, this is first messge The service is unavailable...Copy the code

The zuul-server-provider2 project has enabled a circuit breaker, and The service is unavailable.

data

  • Spring Cloud Zuul example source code
  • Spring Boot, Spring Cloud example learning