Microservices Gateway - SpringCloud Netflix Zuul

Overview

Spring Cloud Zuul is one of the core components of the Spring Cloud Netflix sub-project. It can be used as an API gateway in a microservice architecture and has the following uses:

  • Authentication: Authenticate requests to access each service and reject requests that fail authentication.
  • Monitoring: Monitor system requests, record request response logs, and count current system visits and monitoring status in real time.
  • Stress testing: Helps conduct controlled stress testing of the cluster
  • Grayscale testing: Grayscale release can ensure the stability of the overall system. Problems can be discovered and adjusted during the initial grayscale.
  • Dynamic routing: Distribute requests to specified clients based on the request path
  • Load control: unified control of client request pressure, and requests that exceed the pressure are directly rejected.
  • Static response processing: build partial responses directly at the edge to avoid them flowing into the internal cluster

Build Zuul gateway

Create the zuul-service project and introduce dependencies. This project is based on SpringBoot 2.3.1, SpringCloud Hoxton.SR12

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

Add the following configuration in the application.yml configuration file:

server:
  port: 9080 # 指定运行端口

spring:
  application:
    name: zuul-service # 指定服务名称
    
zuul:
  routes:
    blog:
      path: /baidu/**
      url: https://www.baidu.com  # url用于配置符合path的请求路径路由到的服务地址

@EnableZuulProxyAdd annotations to the startup class

@EnableZuulProxy
@SpringBootApplication
public class ZuulServiceApplication {
    
    

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

Spring Cloud Netflix Zuul provides a number of filters, depending on the Zuul annotations enabled, and @EnableZuulProxyis @EnableZuulServera superset of @EnableZuulServerall filters installed by

Start the project, enter the access address in the browser http://localhost:9080/baidu, and find that the request is routed to the Baidu interface. The Zuul service is successfully built.


Zuul routing configuration

In the previous section, we used paths to match routing rules. The structure of path is as follows

# 其中customName 为用户自定义名称
zuul:
  routes:
    customName:
      # 可使用的通配符有以下几种:
      # ?:单个字符
      # *:任意多个字符,不包含多级路径
      # **:任意多个字符,包含多级路径
      path: xxx

For url path matching, you can also use service name matching

zuul:
  routes:
    # users为用户自定义名称
    users:
      path: /users/**
      # serviceId用于配置符合path的请求路径路由到的服务名称
      serviceId: users-service

Service name matching is also available using simplified configuration

zuul:
  routes:
    service-provider:
      path: /users/**

If only path is configured but not serviceld, customName is equivalent to the service name, that is, service-provider will be regarded as the service name. Use serviceId to register the zuul service to the registration center, such as Eureka, so as to pull the registered service list name to complete the call.

If you want to troubleshoot the configuration, you can use ignored-services

zuul:
  ignoredServices: "*"
  routes:
    users:
      path: /users/**

ignored-services allows you to configure a list of services that are not managed by Zuul. Multiple service names are separated by numbers. The configured services will not be proxied by Zuul. In the above example, all services except user services are ignored.

The routing prefix can be zuul.prefixconfigured via , for example:

zuul:
  prefix: /api
  routes:
    users:
      path: /users/**

Configure the request path prefix. All requests based on this prefix are proxied by the Zuul gateway.


Zuul filter

Zuul defines filters to filter proxy requests and provide additional functional logic, such as permission verification, logging, etc. There is no direct communication between filters. In the request thread, status is shared through RequestContext, which is implemented internally using ThreadLocal.

Zuul filters are divided into pre-filtering, post-routing filtering, post-filtering and exception filtering:

  • Pre-filtering: filtering logic that is executed immediately after the request enters Zuul
  • Post-routing filtering: After the request enters Zuul, Zuul implements request routing and performs filtering logic before the remote service is called.
  • Post-filtering: Execute filtering logic after the remote service call is completed
  • Exception filtering: Execute filtering logic when an exception occurs in any filter or there is no result feedback from the remote service call (call timeout)

The ZuulFilter class and its parent class IZuulFilter provide a total of four abstract methods:

  • filterType: Returns string data, representing the type of the current filter. Optional values ​​are:
    • pre: pre-filter, executed before the request is routed, usually used to handle identity authentication, logging, etc.
    • route: called after the route is executed and before the service is called.
    • error: Executed when an exception occurs in any filter or there is no feedback from the remote service call (timeout), usually used to handle
      exceptions
    • post: is called after the route or error is executed. It is generally used to collect service information, collect statistics on service performance indicators, etc. It can also perform special processing on the response results.
  • filterOrder: Returns int data, used to customize the execution order for multiple filters of the same filterType. The smaller the return value, the higher the priority of the execution order.
  • shouldFilter: Returns boolean data, representing whether the current filter is effective
  • run: specific filter execution logic

Specific examples are as follows:

@Component
public class tokenFilter extends ZuulFilter {
    
    

    @Override
    public String filterType() {
    
    
        //定义过滤器的类型,pre 表示在请求被路由前执行
        return "pre";
    }

    @Override
    public int filterOrder() {
    
    
        //返回int 数据,用于为同一种 filterType 的多个过滤器定制执行顺序
        //返回值越小,执行顺序越优先
        return 0;
    }

    @Override
    public boolean shouldFilter() {
    
    
        //判断过滤器是否生效,true 代表生效
        return true;
    }

    @Override
    public Object run() throws ZuulException {
    
    
        //获取上下文
        RequestContext currentContext = RequestContext.getCurrentContext();
        //获取 request 对象
        HttpServletRequest request = currentContext.getRequest();
        //从请求头获取 token 的参数
        String userToken = request.getParameter("token");
        if (StringUtils.isEmpty(userToken)) {
    
    
            //返回错误提示
            //false:表示不会继续往下执行,不会调用服务接口,直接响应给客户
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseBody("token is null");
            currentContext.setResponseStatusCode(401);
            return null;
        }
        //否则正常执行,调用服务接口...
        return null;
    }
}

Guess you like

Origin blog.csdn.net/CSDN_handsome/article/details/132520940