Spring Cloud Zuul (五)

2019-10-30  本文已影响0人  jeff_chang_liu

API网关服务 Spring Cloud Zuul

API网关是一个更为智能的应用服务器,它的存在就像是整个微服务架构系统的门面,所有的外部客户端访问都需要经过它来进行调度和过滤。除了需要实现请求路由,负载均衡及校验过滤等功能外还需要与服务治理框架的结合,请求转发时的熔断机制,服务的聚合等一系列高级功能。

在Spring Cloud中提供了基于Netflix Zuul实现的API网关组件Spring Cloud Zuul。对于路由规则与服务实例的维护,Spring Cloud Zuul通过与Spring Cloud Eureka进行整合,将自身注册为Eureka治理下的应用,同时从Eureka获得了所有其他微服务的实例信息,使得将维护服务实例的工作交给了服务治理框架自动完成。不在需要人工介入。对于路由规则的维护,Zuul默认将通过以<font color=#FF0000>服务名</font>作为ContextPath的方式创建路由映射。对于类似签名校验及登录校验,可以独立成一个单独的服务存在,只是它并不是给各个微服务调用,而是在API网关服务上进行统一调用来对微服务接口做前置过滤,实现对微服务接口的拦截和校验。Spring Cloud Zuul提供了一套过滤器机制,可以很好地支持这样的任务。

1. 快速集成 Spring Cloud Zuul

1.1 构建网关

  1. 创建基础Spring Boot工程

  2. 添加依赖: spring-cloud-starter-zuul

  3. 在主类上使用@EnableZuulProxy注解开启Zuul的API网关服务功能

  4. 配置Zuul应用的基础信息

    spring.application.name=api-gateway
    spring.port=8080
    

1.2 请求路由

启动Eureka服务注册中心和微服务应用

1.3 请求过滤

Zuul允许在API网关上通过定义过滤器实现对请求的拦截与过滤,只需要继承ZuulFilter抽象类并定义它的四个抽象函数。

public class AccessFilter extends ZuulFilter {
    /**
    * 过滤器类型,决定过滤器在请求的哪个生命周期执行
    */
    @Override
    public String filterType() {
        return "pre";
    }
    
    /**
    * 过滤器的执行顺序,当同一阶段存在多个过滤器时,需要根据该返回值指定执行顺序
    */
    @Override
    public int filterOrder() {
        return 0;
    }
    
    /**
    * 过滤器是否执行
    */
    @Override
    public boolean shouldFilter() {
        return true;
    }
    
    /**
    * 过滤器任务
    */
    @Override
    public Object run() {
        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;
    }
}

定义Zuul拦截器配置,并添加拦截器

@Configuration
public class ZuulFilterConfiguration {
    
    @Bean
    public AccessFilter accessFilter() {
        return new AccessFilter();
    }
}

2. 路由详解

2.1 服务路由配置

简洁配置方式

zuul.routes.hello-service=/api-a/**

2.2 服务路由默认规则

为Spring Cloud Zuul构建的API网关服务引入Spring Cloud Eureka之后,它为Eureka中的每个服务都自动创建一个默认路由规则,默认路由规则的path使用serviceId配置的服务名作为请求前缀,以hello-service为例:

zull.routes.hello-service.path=/hello-service/**
zull.routes.hello-service.serviceId=hello-service

2.3 路径匹配

在Spring Cloud Zuul中,路由匹配的路径表达式采用了Ant风格定义

通配符 说明
? 匹配任意单个字符
* 匹配任意数量字符
** 匹配任意数量字符,支持多级目录

2.4 忽略表达式

Spring Cloud Zuul忽略表达式参数zuul.ignored-patterns用来设置不希望被API网关进行路由的URL表达式。

zuul.ignored-patterns=/**/hello/**

2.5 Cookie与头信息

默认情况下,Spring Cloud Zuul请求路由时,会过滤掉HTTP请求头信息中的一些敏感信息,防止它们被传递到下游的外部服务器。默认的敏感头信息通过zuul.sensitiveheaders参数定义,包括Cookie, Set-Cookie, Authorization三个属性。

解决方案:

2.6 Hystrix与Ribbon支持

Zuul自身包含了对Hystrix和Ribbon的模块依赖,因此Zuul拥有线程隔离和断路器的自我保护功能,以及对服务调用的客户端负载均衡功能。当使用path和url的映射关系配置路由规则时没有上述功能,因此使用Zuul时尽量使用path和serviceId的组合进行配置。参数配置如下:

ribbon:
  ReadTimeout: 600000      // 设置路由转发请求的超时时间
  ConnectTimeout: 600000   // 设置路由转发请求,创建请求连接的超时时间
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 60000  // 设置API网关路由转发请求HystrixCommand执行超时时间

2.7 过滤器详解

在Zuul中,路由功能真正运行时,它的路由映射和请求转发由几个不同的过滤器完成。路由映射主要通过pre类过滤器完成,它将请求路径与配置的路由规则进行匹配,找到需要转发的路由地址。请求转发的部分由route类过滤器完成。

在Spring Cloud Zuul中实现的过滤器必须包含4个基本特征:过滤类型,执行顺序,执行条件,具体操作。实际上它们就是ZuulFilter接口中定义的4个抽象方法:

String filterType();
int filterOrder();
boolean shouldFilter();
Object run();

2.8 异常处理

在Spring Cloud Zuul中,在HTTP请求生命周期的各个阶段默认实现了一批核心过滤器,在API网关服务启动的时候被自动加载和启用,但核心过滤器中没有实现error阶段的过滤器,因此需要在自定义过滤器中处理异常内容:

上一篇下一篇

猜你喜欢

热点阅读