SpringCloud系列之Zuul网关和Zuul过滤器

Zuul是SpringCloud全家桶的微服务网关。所有从app或者网站(第三方)来的请求都会经过Zuul到达后端的Netflix应用程序。
首页 新闻资讯 行业资讯 SpringCloud系列之Zuul网关和Zuul过滤器

a9b283f3789c8684747868a8ecd90a52555d18.png

Zuul网关

什么是Zuul网关?

Zuul是SpringCloud全家桶的微服务网关。所有从app或者网站(第三方)来的请求都会经过Zuul到达后端的Netflix应用程序。作为一个边界性质的应用程序,Zuul提供了动态路由、监控、弹性负载和安全功能。

Zuul底层利用filter实现如下功能:

  1. 认证和安全,识别每个需要认证的资源,拒绝不服务要求的请求。

  2. 性能检测,在服务边界追踪并统计数据,提供精确的生产视图。

  3. 动态路由,根据需要将请求动态路由到后端集群。

  4. 压力测试,逐渐增加对集群的流量以及了解其性能。

  5. 负载卸载,预先为每种类型的请求分配容量,当请求超过流量时自动丢弃。静态资源处理,直接在边界返回某种响应。

  6. 静态资源处理,直接在Zuul处理静态资源并响应,而并非转发这些请求到内部集群中。

  7. 多区域弹性,跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。

Zuul网关Demo

引入jar包:

复制

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
    <version>1.3.5.RELEASE</version>
</dependency>
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

配置文件:application.yml。

复制

server:  port: 7004  # 端口spring:  application:name: zuul-getway  # 服务名eureka:  client:service-url:      defaultZone: http://jack:666@localhost:8764/eureka/  # 需要注册到eureka
  instance:instance-id: ${spring.application.name}:${server.port}zuul:  routes:order-service: /od/**  # 对某个服务自定义路由规则    serviceId: order-service # 这个配置可以实现负载均衡,默认是轮询  # 设置某些服务不要进行反向代理 进行路由,多个服务用逗号隔开  ignored-services: order-service, user-service  prefix: /api # 请求路径的前缀
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

查看是否注册到eureka。

65d102029b5465211d4135a4fa94d61be015bd.png

Eureka注册中心

访问路径:

localhost:7004/api/od/getOrder?token=1235。

(后面带token是因为我配置了pre过滤器,下面会介绍)。

947816732b045f482e33216a3fc20c3afac8db.png

Zuul过滤器

Zuul四种过滤器类型,这些类型对应请求的生命周期

  • pre(前置):在请求被路由之前调用。可利用这种过滤器来实现身份认证、在集群中选择请求的微服务,记录调试等。

  • routing(路由):将请求路由到微服务。用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务。

  • post(后置):在路由到微服务后执行。可用于响应添加标准的http header、收集统计信息和指标、将响应从微服务发送到客户端。

  • error(错误):在其他阶段发送错误时执行该过滤器。

注:除了默认的过滤器类型以外Zuul还允许创建自定义的过滤器类型。

如何禁用过滤器?

很简单,只需设置zuul.ClassName.filterType.disable=true ,即可禁用SimpleClassName所对应的过滤器。例如:zuul.TokenFilter.pre.disable=true; 即可禁用TokenFilter过滤器。

pre过滤器

例子: 鉴权认证。如果参数带了token就允许访问。

复制

/** * pre过滤器 * @Author Big.Hu */@Componentpublic class TokenFilter extends ZuulFilter {@Overridepublic Object run() {System.err.println("执行pre前置过滤器。。。。。。。。。");RequestContext currentContext = RequestContext.getCurrentContext();HttpServletRequest request = currentContext.getRequest();StringBuffer requestURL = request.getRequestURL();System.out.println("requestURL:" + requestURL);
        // 获取请求的参数String token = request.getParameter("token");if (StringUtils.isEmpty(token)) {
            // 如果参数为空则过滤该请求,不对其进行路由currentContext.setSendZuulResponse(false);
            // 设置错误码:401currentContext.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);currentContext.set("SUCCESS", false);
        } else {
            // 不过滤该请求,对其进行路由currentContext.setSendZuulResponse(true);
            // 设置成功码:200currentContext.setResponseStatusCode(HttpStatus.SC_OK);currentContext.set("SUCCESS", true);
        }System.out.println("token:" + token);return null;
    }/**     * 当前filter类型:pre、post、route、error     */@Overridepublic String filterType() {return FilterConstants.PRE_TYPE;
    }/**     * 表示当前filter优先级     */@Overridepublic int filterOrder() {return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }/**     * 是否执行该过滤器?     **/@Overridepublic boolean shouldFilter() {return true;
    }
}
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

  • 19.

  • 20.

  • 21.

  • 22.

  • 23.

  • 24.

  • 25.

  • 26.

  • 27.

  • 28.

  • 29.

  • 30.

  • 31.

  • 32.

  • 33.

  • 34.

  • 35.

  • 36.

  • 37.

  • 38.

  • 39.

  • 40.

  • 41.

  • 42.

  • 43.

  • 44.

  • 45.

  • 46.

  • 47.

  • 48.

  • 49.

  • 50.

  • 51.

  • 52.

  • 53.

POST过滤器

例: 在返回的时候设置一个cookie。

复制

/** * Post过滤器 * @Author Big.Hu */@Componentpublic class PostFilter extends ZuulFilter {/**     * POST过滤器:在route和error过滤器之后执行     */@Overridepublic String filterType() {return FilterConstants.POST_TYPE;
    }@Overridepublic int filterOrder() {return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
    }@Overridepublic boolean shouldFilter() {return true;
    }@Overridepublic Object run() {System.err.println("执行Post过滤器。。。。。。。。。");RequestContext currentContext = RequestContext.getCurrentContext();HttpServletResponse response = currentContext.getResponse();Cookie cookie = new Cookie("name", "Jack.Hu");cookie.setMaxAge(60 * 60 * 24);response.addCookie(cookie);return null;
    }
}
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

  • 19.

  • 20.

  • 21.

  • 22.

  • 23.

  • 24.

  • 25.

  • 26.

  • 27.

  • 28.

  • 29.

  • 30.

  • 31.

  • 32.

访问路径:

localhost:7004/api/od/getOrder。

(没带token参数)请求被pre过滤器过滤掉了。

b3f50cd597125ba20139037a0e1202204ef347.png

不带token请求

带上token参数请求成功!

54d9bca09fd457fc03b48320b211d10ff6eb7f.png

带token请求

再按f12看post过滤器设置的cookie。

48af206838d02f59195964ed5badaf93403a75.png

查看cookie

控制台:

b9fd5186925af0ece405825afd23276fd16d9b.png

控制台