Spring Cloud Zuul自定义过滤器的实现

构建Zuul自定义过滤器,限制ip频繁请求

自定义zuul过滤器其实很简单

1. 首先pom文件得先引入zuul依赖

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

2. 创建一个类,继承自ZuulFilter

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

/**
 * 构建zuul自定义过滤器
 */
@Component
public class MyFilter extends ZuulFilter {

  /**
   * 定义过滤器的类型
   * pre:在请求被路由之前执行
   * route:在路由请求的时候执行
   * post:请求路由以后执行
   * error:处理请求时发生错误的时候执行
   *
   * @return 过滤器的类型
   */
  @Override
  public String filterType() {
    return "pre";
  }

  /**
   * 过滤器执行的顺序,配置多个有顺序的过滤
   * 执行顺序从小到大
   *
   * @return 执行顺序
   */
  @Override
  public int filterOrder() {
    return 1;
  }

  /**
   * 是否开启过滤器
   * true:开启
   * false:禁用
   *
   * @return 是否开启过滤器
   */
  @Override
  public boolean shouldFilter() {
    return true;
  }

  /**
   * 过滤器的业务实现
   *
   * @return null 没有意义
   * @throws ZuulException 异常信息
   */
  @Override
  public Object run() throws ZuulException {

    System.out.println("per zuul filter...");

    return null;
  }
}

自定义类上需要加上 @Component 注解
a. filterType()方法,定义过滤器的类型,返回的就是字符串,有以下4种类型

  • pre:在请求被路由之前执行
  • route:在路由请求的时候执行
  • post:请求路由以后执行
  • error:处理请求时发生错误的时候执行

b. filterOrder()方法,过滤器执行的顺序
c. shouldFilter()方法,是否开启过滤器,true开启,false不开启
d. run()方法,过滤器的业务实现,在这里写实现逻辑的具体代码

3. 限制ip频繁请求,示例代码

import com.imooc.grace.result.GraceJsonResult;
import com.imooc.grace.result.ResponseStatusEnum;
import com.imooc.utils.IPUtil;
import com.imooc.utils.JsonUtils;
import com.imooc.utils.RedisOperator;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 限制ip频繁请求
 */
@Component
public class BlackIpFilter extends ZuulFilter {

  /**
   * ip连续请求的次数
   */
  private static final int CONTINUE_COUNTS = 10;
  /**
   * ip判断的时间间隔,单位秒
   */
  private static final int TIME_INTERVAL = 10;
  /**
   * 限制的时间,单位秒
   */
  private static final int LIMIT_TIMES = 15;

  @Autowired
  private RedisOperator redisOperator;

  @Override
  public String filterType() {
    return "pre";
  }

  @Override
  public int filterOrder() {
    // 这里设置为2,上面那个过滤器设置为1,则执行顺序为 1->2,大家可以测试一下
    return 2;
  }

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

  @Override
  public Object run() throws ZuulException {
    // 获取上下文对象
    RequestContext currentContext = RequestContext.getCurrentContext();
    HttpServletRequest request = currentContext.getRequest();
    // 获取ip
    String requestIp = IPUtil.getRequestIp(request);

    // 判断该ip在10秒内请求次数是否超过10次,超过则限制该ip15秒内不能访问,15秒后再放行
    final String ipRedisKey = "zuul-ip:" + requestIp;
    final String ipRedisLimitKey = "zuul-ip-limit:" + requestIp;

    // 获取当前ip这个key的剩余时间
    long limitLeftTime = redisOperator.ttl(ipRedisLimitKey);
    // 判断该ip是否还有剩余时间
    if (limitLeftTime > 0) {
      stopRequest(currentContext);
      return null;
    }

    // 在redis中累加ip的请求次数
    long requestCounts = redisOperator.increment(ipRedisKey, 1);
    if (requestCounts == 1) {
      redisOperator.expire(ipRedisKey, TIME_INTERVAL);
    }

    if (requestCounts > CONTINUE_COUNTS) {
      // 限制ip访问
      redisOperator.set(ipRedisLimitKey, ipRedisLimitKey, LIMIT_TIMES);
      stopRequest(currentContext);
    }

    return null;
  }

  private void stopRequest(RequestContext context) {
    // 停止zuul继续向下路由,禁止请求通信
    context.setSendZuulResponse(false);
    // 返回响应码200
    context.setResponseStatusCode(200);

    // TODO 要返回提示的json内容(可以自定义任何响应内容)
    // 例如 {"status":544,"msg":"请求过于频繁,请稍后再试","success":false,"data":null}
    String result = "json内容";

    // 设置返回内容
    context.setResponseBody(result);
    // 设置编码
    context.getResponse().setCharacterEncoding("utf-8");
    // 设置返回内容格式为json
    context.getResponse().setContentType(MediaType.APPLICATION_JSON_VALUE);
  }
}

这里使用了redis来记录ip请求次数和控制时间间隔

获取ip工具类 IPUtil

import javax.servlet.http.HttpServletRequest;

/**
 * 获取ip工具类
 */
public class IPUtil {

  /**
   * 获取请求IP:
   * 用户的真实IP不能使用request.getRemoteAddr()
   * 这是因为可能会使用一些代理软件,这样ip获取就不准确了
   * 此外我们如果使用了多级(LVS/Nginx)反向代理的话,ip需要从X-Forwarded-For中获得第一个非unknown的IP才是用户的有效ip。
   */
  public static String getRequestIp(HttpServletRequest request) {
    String ip = request.getHeader("x-forwarded-for");
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("HTTP_CLIENT_IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getRemoteAddr();
    }
    return ip;
  }
}

到此这篇关于Spring Cloud Zuul自定义过滤器的实现的文章就介绍到这了,更多相关Spring Cloud Zuul过滤器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring Cloud Zuul添加过滤器过程解析

    这篇文章主要介绍了Spring Cloud Zuul添加过滤器过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Zuul作为网关的其中一个重要功能,就是实现请求的鉴权.而这个动作我们往往是通过Zuul提供的过滤器来实现的. 一.过滤器方法的作用 想要使用Zuul实现过滤功能,我们需要自定义一个类继承ZuulFilter类,并实现其中的四个方法,我们先看一下这四个方法的作用是什么 public class MyFilter extends

  • 深入解析Spring Cloud内置的Zuul过滤器

    前言 Spring Cloud默认为Zuul编写并启用了一些过滤器,这些过滤器有什么作用呢?我们不妨按照@EnableZuulServer.@EnableZuulProxy两个注解进行展开,相信大家对这两个注解都不陌生(至少都见过吧).如果觉得陌生也没有关系,可将@EnableZuulProxy简单理解为@EnableZuulServer的增强版.事实上,当Zuul与Eureka.Ribbon等组件配合使用时, @EnableZuulProxy是我们常用的注解. 在Spring Cloud的官方

  • 详解SpringCloud Zuul过滤器返回值拦截

    Zuul作为网关服务,是其他各服务对外中转站,通过Zuul进行请求转发.这就涉及到部分数据是不能原封返回的,比如服务之间通信的凭证,用户的加密信息等等. 举个例子,用户服务提供一个登录接口,用户名密码正确后返回一个Token,此Token作为用户服务的通行证,那么用户登录成功后返回的Token就需要进行加密或者防止篡改处理.在到达用户服务其他接口前,就需要对Token进行校验,非法的Token就不需要转发到用户服务中了,直接在网关层返回信息即可. 要修改服务返回的信息,需要使用的是Zuul的过滤

  • 深入理解Spring Cloud Zuul过滤器

    前言 过滤器是Zuul的核心组件,这篇文章我们来详细讨论Zuul的过滤器.下面话不多说,来看看详细的介绍吧. 过滤器类型与请求生命周期 Zuul大部分功能都是通过过滤器来实现的.Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期. (1) PRE:这种过滤器在请求被路由之前调用.我们可利用这种过滤器实现身份验证.在集群中选择请求的微服务.记录调试信息等. (2) ROUTING:这种过滤器将请求路由到微服务.这种过滤器用于构建发送给微服务的请求,并使用Apache Htt

  • SpringCloud Zuul过滤器实现登陆鉴权代码实例

    1.新建一个filter'包 2.新建一个类,实现ZuulFilter,重写里面的方法 3.在顶部类添加注解,@Component,让Spring扫描 /** * 登陆过滤器 */ @Component public class LoginFilter extends ZuulFilter { @Override public String filterType() { //前置过滤器 return PRE_TYPE; } @Override public int filterOrder() {

  • SpringCloud Zuul过滤器和谷歌Gauva实现限流

    前提: 已经配置Zuul网关 参考: https://www.jb51.net/article/182894.htm 限流方式: 1)nginx层限流 2)网关层限流 1.添加限流过滤器 import com.alibaba.fastjson.JSON; import com.google.common.util.concurrent.RateLimiter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.

  • Spring Cloud Zuul自定义过滤器的实现

    构建Zuul自定义过滤器,限制ip频繁请求 自定义zuul过滤器其实很简单 1. 首先pom文件得先引入zuul依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> 2. 创建一个类,继承自ZuulFilter import

  • Spring Cloud zuul自定义统一异常处理实现方法

    Zuul在springcloud微服务体系中提供filer和router功能,是微服务不可或缺的部分.filer处理默认实现的外还可以自定义进行授权.限流.安全校验等,router完全可以替代Nginx反向代理.Zuul异常处理就是由SendErrorFilter完成. 在我们应用过程我们发现使用默认的异常filter有两个问题不是很友好: 1.无法快速识别出是否是请求路由的服务超时还是没有任何可用节点,发生错误只能查看日志通过堆栈去定位: 2.无法兼容自定义的譬如{code:500,msg:"

  • spring cloud zuul 与 sentinel的结合使用操作

    spring cloud zuul 与 sentinel结合 本来大型服务处理请求超时,限流,降级熔断工作用hystrix,但是这个这个项目不再更新了,虽说它现在提供的版本不会影响到大多数开发者的使用,但是长远考虑,被更换是一件必然的事,而且现在像resilience4j, Sentinel这样的替代品出现,今天我们就看看使用zuul 与 Sentinel整合,实现降级与超时处理,其实网上有很多这样的教程,这里我只是做一个自己的笔记而已 1.必须的依赖 <dependency> <gro

  • 关于服务网关Spring Cloud Zuul(Finchley版本)

    目录 一.Zuul简介 二.请求路由 2.1传统路由 2.2面向服务的路由 三.路由规则 3.1默认路由规则 3.2自定义路由规则 四.Zuul的过滤器 五.设置熔断 六.实战 6.1pom文件 6.2配置文件 6.3过滤器配置 6.4熔断配置 6.5启动类 一.Zuul简介 Zuul作为微服务系统的网关组件,用于构建边界服务(Edge Service),致力于动态路由.过滤.监控.弹性伸缩和安全.其在微服务架构中有着重要的作用,主要体现在以下六个方面: Zull.Ribbon以及Eureka相

  • 详解Spring Cloud Zuul网关修改为短连接方法

    目录 一.问题分析 二.解决方式 一.问题分析 之前在用zuul网关的时候,请求几次然后连接就断开了.原因是因为http1.1之后,默认走的都是connection=keep-alive 长连接.但没有心跳维持,顾1分钟断开一次.但RestFul一般都是走短连接就行了.因此想着只要修改头部connection属性就行了. 就是在过滤器中修改Zuul的RequestContext ctx对象 //设置请求为短连接 ctx.addZuulRequestHeader("connection"

  • 详解Spring Cloud Zuul 服务网关

    有了Eureka服务注册发现.Hystrix断路器.Ribbon服务调用负载均衡,以及spring cloud config 集群配置中心,似乎一个微服务框架已五脏俱全,last but not least,一个服务网关却不可或缺. Spring Cloud Zuul路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务.Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器. Zuul介绍 在整个Spring Cloud微服务框架里,Zuul扮演着"智能网

  • Spring Cloud Zuul路由规则动态更新解析

    这篇文章主要介绍了Spring Cloud Zuul路由规则动态更新解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 背景 Spring Cloud Zuul 作为微服务的网关,请求经过zuul路由到内部的各个service,由于存在着新增/修改/删除服务的路由规则的需求,zuul的路由规则的动态变更功能 提供了 无须重启zuul网关,即可实时更新,现有如下几种方式: 一.基于refresh + config-server事件动态刷新 (1)

  • spring cloud zuul增加header传输的操作

    spring cloud zuul增加header传输 在使用OAuth2.0传输权限认证,为了再调用其他的项目的时候获取token,必须在token下传到其他各个服务 @Component public class KeyUserFilter extends ZuulFilter { private static final Logger logger = LoggerFactory.getLogger(KeyUserFilter.class); @Override public Object

  • 利用Spring Cloud Zuul实现动态路由示例代码

    前言 本文主要给大家介绍了关于Spring Cloud Zuul实现动态路由的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. Zuul 是提供动态路由,监控,弹性,安全等的边缘服务.Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门. Zuul 可以适当的对多个 Amazon Auto Scaling Groups 进行路由请求. 首先新建maven项目,加入如下依赖 <dependencyManagement> <depend

随机推荐