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

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>

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 # 请求路径的前缀

查看是否注册到eureka
在这里插入图片描述
访问路径:localhost:7004/api/od/getOrder?token=1235
(后面带token是因为我配置了pre过滤器)
在这里插入图片描述

Zuul过滤器

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

  1. pre(前置):在请求被路由之前调用。可利用这种过滤器来实现身份认证、在集群中选择请求的微服务,记录调试等。
  2. routing(路由):将请求路由到微服务。用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务。
  3. post(后置):在路由到微服务后执行。可用于响应添加标准的http header、收集统计信息和指标、将响应从微服务发送到客户端。
  4. error(错误):在其他阶段发送错误时执行该过滤器。

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

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

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

package com.hj.zuulGetway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * pre过滤器
 * @Author Jack.Hu
 */
@Component
public class TokenFilter extends ZuulFilter {

    @Override
    public 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);
            // 设置错误码:401
            currentContext.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
            currentContext.set("SUCCESS", false);
        } else {
            // 不过滤该请求,对其进行路由
            currentContext.setSendZuulResponse(true);
            // 设置成功码:200
            currentContext.setResponseStatusCode(HttpStatus.SC_OK);
            currentContext.set("SUCCESS", true);
        }
        System.out.println("token:" + token);
        return null;
    }

    /**
     * 当前filter类型:pre、post、route、error
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 表示当前filter优先级
     */
    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    /**
     * 是否执行该过滤器?
     **/
    @Override
    public boolean shouldFilter() {
        return true;
    }
}

POST过滤器
例子: 在返回的时候设置一个cookie

package com.hj.zuulGetway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

/**
 * Post过滤器
 * @Author Jack.Hu
 */
@Component
public class PostFilter extends ZuulFilter {

    /**
     * POST过滤器:在route和error过滤器之后执行
     */
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
    }

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

    @Override
    public 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;
    }
}

访问路径:localhost:7004/api/od/getOrder
(没带token参数)请求被pre过滤器过滤掉了
在这里插入图片描述
带上token参数请求成功!
在这里插入图片描述
再按f12看post过滤器设置的cookie
在这里插入图片描述
控制台
在这里插入图片描述

以上文章有什么不对的地方,望大佬们不吝赐教!

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值