美文网首页
Spring Cloud Zuul (五)

Spring Cloud Zuul (五)

作者: jeff_chang_liu | 来源:发表于2019-10-30 16:46 被阅读0次

    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服务注册中心和微服务应用

    • 传统路由方式

      对api-gateway服务增加路由配置规则

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

      定义发往API网关的请求中,所有符合/api-a-url/**规则的访问都将被路由转发到http://localhost:8081/地址上。api-a-url部分为路由的名称,可任意定义,一组path与url映射关系的路由名要相同。

    • 面向服务的路由

      ​ Spring Cloud Zuul实现了与Spring Cloud Eureka的无缝整合,可以让路由的path不是映射具体的url,而是映射某个具体的服务,而具体的服务则交给Eureka的服务发现机制去自动维护,称之为面向服务的路由。

      1. 添加依赖:spring-cloud-starter-eureka

      2. 配置Zuul的Eureka注册中心的位置

      3. 配置服务路由

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

        简洁配置方式

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

    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三个属性。

    解决方案:

    • 设置全局参数为空覆盖默认值

      zuul.sensitiveheaders=
      
    • 设置指定路由的参数

      // 对指定路由开启自定义敏感头
      zuul.routes.<router>.customSensitiveHeaders=true
      // 将指定路由的敏感头设置为空
      zuul.routes.<router>.sensitiveheaders=
      

    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();
    
    • filterType:过滤器类型
      • pre:可以再请求被路由前调用
      • routing:在路由请求时被调用
      • post:在routing和error过滤器之后被调用
      • error:处理请求时发生错误时被调用
    • filterOrder:过滤器执行顺序,数值越小优先级越高
    • shouldFilter:是否执行过滤器
    • run:过滤逻辑

    2.8 异常处理

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

    • try-catch处理

      error相关三个主要参数:

      1. error.status_code:错误码
      2. error.exception:Exception异常对象
      3. error.message:错误信息(优先级高于Exception对象中的message)
      public Object run() {
          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;
      }
      
    • ErrorFilter处理

      在请求生命周期的pre,route,post三个阶段有异常抛出的时候都会进入到error阶段处理,通过创建error类型过滤器捕获异常信息并处理。

      public Object run() {
          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;
      }
      

    相关文章

      网友评论

          本文标题:Spring Cloud Zuul (五)

          本文链接:https://www.haomeiwen.com/subject/bbxavctx.html