Zuul网关基本使用

320 阅读3分钟

Zuul网关基本功能

  • 路由
  • 认证
  • 负载均衡
  • 限流

1.路由

将不同的REST请求转发到不同的服务提供者,还可以统一访问端口

2.认证

网关直接暴露在公网上,客户端如果需要访问某个微服务,通常会将登录后的token传过来,网关层会对token进行校验,如果token无效则不允许访问服务。认证可以结合Spring Security

3.负载均衡

在微服务中,每一个Provider都会有多个实例,Zuul可以通过负载均衡策略在多个Provider中选择目标

4.限流

高并发场景下瞬时流量不可预估,限流可以保证服务的稳定性。如果请求流量超过服务负载能力时,很容易造成服务崩溃

Zuul路由规则配置

Zuul路由有两种配置规则,一种是Url,另外一种是服务ID

1.Url

Url配置是通过实际地址进行转发,配置规则如下:

zuul:
  routes:
    #路由规则名
    demo:
      #路由匹配规则
      path: /demo/**
      #转发地址
      url: https://juejin.cn
      #是否去掉前缀,false: 不去掉,true:去掉
      strip-prefix: false

此规则说明Zuul会将收到匹配/demo/** 路径的请求转发到 juejin.cn 地址

2.服务id

此方案需要在结合Spring Cloud和Eureka一起使用

zuul:
  routes:
    #路由规则名
    demo:
      #路由匹配规则
      path: /demo/**
      #转发地址
      serviceId: target
      #是否去掉前缀,false: 不去掉,true:去掉
      strip-prefix: false

此规则说明Zuul会将收到匹配/demo/** 路径的请求转发注册到Eureka注册中心上并且服务Id是target的服务

敏感头部

在http请求中,可能会在header中携带敏感信息,比如Cookie、token等。如果请求需要转发到外部,那么就需要过滤敏感信息,防止信息泄露。Zuul提供了sensitiveHeaders来过滤敏感header,配置如下:

zuul:
  routes:
    #路由规则名
    demo:
      #路由匹配规则
      path: /demo/**
      #转发地址
      url: https://juejin.cn
      #是否去掉前缀,false: 不去掉,true:去掉
      strip-prefix: false
      #敏感请求头信息
      sensitiveHeaders: Cookie,Set-Cookie,backend,token

Zuul在进行请求转发时,会过滤掉通过sensitiveHeaders配置的请求头信息

Zuul过滤器

1.过滤器类型

Zuul过滤器有4种标准过滤器类型,分别是:pre、router、post、error,在FilterConstant种定义了者4种过滤器类型常量

pre

pre类型的过滤器的执行时机是Zuul网关接收到该请求,但还没有做路由的前置过滤处理

router

router类型的过滤器的执行时机是前置过滤处理之后,请求转发之前

post

post类型的过滤器的执行时机是请求返回之后,可以对返回结果进行处理

error

error类型的过滤器的执行时机上面三个类型的过滤器发生错误之后

2.过滤器创建

Zuul过滤器的创建方式是继承ZuulFilter类,实现其方法

filterType()方法

此方法返回过滤器类型,即pre或者error

filterOrder()

此方法返回过滤器执行顺序,值越小执行顺序越靠前

shouldFilter()

此方法返回当前过滤器是否需要执行,返回true表示需要执行。示例:

public boolean shouldFilter() {
    RequestContext context = RequestContext.getCurrentContext();
    //一般都会通过context.sendZuulResponse()方法判断是否应该执行过滤器
    return context.sendZuulResponse();
}

在RibbonRoutingFilter过滤器源码中,也使用了context.sendZuulResponse()进行判断,源码如下:

public boolean shouldFilter() {
   RequestContext ctx = RequestContext.getCurrentContext();
   return (ctx.getRouteHost() == null && ctx.get(SERVICE_ID_KEY) != null
         && ctx.sendZuulResponse());
}

run()

此方法为过滤器具体执行逻辑