美文网首页
SpringCloud-6

SpringCloud-6

作者: 我叫土豆但他们喊我猫猫 | 来源:发表于2019-08-04 21:56 被阅读0次

    5.3 Zuul过滤

    1.简介

    Zuul的大部分功能都是通过过滤功能来完成的,Zuul可以提供四种标准类型的过滤,如下图所示:

    1. Pre: 过滤规则在路由之前起作用。可以利用“Pre”过滤器实现用户鉴权,记录请求日志等;

    2. Routing:过滤规则在路由时发生作用。可以利用“Routing”过滤器实现动态路由、灰度发布、A/B测试、负载限流等。

    3. Post:过滤规则在路由之后发生作用。可以利用"Post"过滤器收集统计信息和指标,将微服务的相应写入Http响应并返回给服务消费者;

    4. Error:过滤规则路由过程中发生错误时发生作用。可以利用Error过滤器记录错误日志,并对错误进行二次处理等。

    总结:在过滤器之间用RequestContext传递消息。RequestContext存储的内容包括路由目标地址、错误信息、请求信息、响应信息等。Zuul的过滤规则也可以用基于JVM的语言编写,包括Java、Python、Groovy等。

    2. 使用过滤功能

    在Zuul中使用过滤器,只需要继承ZuulFilter抽象类实现其定义的四个抽象函数就可对请求进行拦截与过滤。

    ①:创建一个实现类:

    <pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="java" cid="n317" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 0px; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> public class ExampleFilter extends ZuulFilter{
    /*

    • Zuul过滤器需要实现四个函数;filterType:代表过滤器类型;filterOrder:执行顺序;
    • shouldFilter:是否启动过滤器;run:过滤器的逻辑
    • */
      private static Logger logger = LoggerFactory.getLogger(ExampleFilter.class);
      @Override
      public String filterType() {
      return "pre";
      }

      @Override
      public int filterOrder() {
      return 0;
      }

      @Override
      public boolean shouldFilter() {
      return true;
      }

      @Override
      public Object run() {
      RequestContext context = RequestContext.getCurrentContext();
      HttpServletRequest request = context.getRequest();
      logger.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
      Object accessToken = request.getParameter("accessToken");
      if(accessToken == null) {
      logger.warn("access token is empty");
      context.setSendZuulResponse(false);
      //context.setResponseStatusCode(401);
      context.setResponseBody("This is 401 error!");
      return null;
      }
      logger.info("It's access token ok");
      return null;
      }
      }</pre>

    在使用过滤器时,只需要实现其中的四个函数即可:

    filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型。

    filterOrder:通过int值来定义过滤器的执行顺序。

    shouldFilter:返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关。

    run:过滤器的具体逻辑。

    注,通过ctx.setSendZuulResponse(false)令zuul过滤该请求,不对其进行路由,然后通过ctx.setResponseStatusCode(401)设置了其返回的错误码,当然我们也可以进一步优化我们的返回,比如,通过ctx.setResponseBody(body)对返回body内容进行编辑等。

    ②:实例化过滤器(在主类中):

    1564926554673

    ③:测试过滤器是否起到作用:

    访问路径1:http://localhost:8523/api-a/add?a=1&b=2

    结果1:由于没有传参accessToken,此时会返回一个错误消息。

    image

    访问路径2:http://localhost:8523/api-a/add?a=1&b=2&accessToken=token

    结果2:此时会返回一个计算结果。

    image

    对应的控制台页打印出相关信息:

    image

    注:由于服务路由Zuul中也包含了断路器的功能,所以即使某台服务器发生故障,也不会影响整体服务之间的关联和运行。

    测试:关闭discovery服务器,此时通过路由的映射关系去访问其对应的路径,则会弹出错误提示:

    image

    5.4 总结

    对于微服务架构中,服务路由是必不可缺的一部分,主要有以下几点体现:

    1. 不仅仅实现了路由功能来屏蔽诸多服务细节,更实现了服务级别、均衡负载的路由。

    2. 实现了接口权限校验与微服务业务逻辑的解耦。通过服务网关中的过滤器,在各生命周期中去校验请求的内容,将原本在对外服务层做的校验前移,保证了微服务的无状态性,同时降低了微服务的测试难度,让服务本身更集中关注业务逻辑的处理。

    3. 实现了断路器,不会因为具体微服务的故障而导致服务网关的阻塞,依然可以对外服务。

    相关文章

      网友评论

          本文标题:SpringCloud-6

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