SpringCloud使用Zuul限流(Zuul+Ratelimit)

微服务开发中有时需要对API做限流保护,防止网络攻击,比如做一个短信验证码API,限制客户端的请求速率能在一定程度上抵御短信轰炸攻击,降低损失。微服务网关是每个请求的必经入口,非常适合做一些API限流、认证之类的操作,本文介绍Zuul如何进行限流操作,对Zuul不了解的可以参考我这篇文章:SpringCloud组件之Zuul

一、Ratelimit相关配置介绍

1、限流策略

限流粒度/类型 说明
Authenticated User 使用经过身份验证的用户名或“匿名”
Request Origin 使用用户原始请求
URL 使用下游服务的请求路径
ROLE 使用经过身份验证的用户角色
Request method 使用HTTP请求方法
Global configuration per service 这个不验证请求Origin,Authenticated User或URI,要使用这个,请不要设置type

2、可用的实现

存储类型 说明
consul 基于consul
redis 基于redis,使用时必须引入redis相关依赖
JPA 基于SpringDataJPA,需要用到数据库
MEMORY 基于本地内存,默认
BUKET4J 使用一个Java编写的基于令牌桶算法的限流库

Bucket4j实现需要相关的bean @Qualifier("RateLimit"):

  • JCache - javax.cache.Cache
  • Hazelcast - com.hazelcast.core.IMap
  • Ignite - org.apache.ignite.IgniteCache
  • Infinispan - org.infinispan.functional.ReadWriteMap

3、常见的配置属性

属性名 默认值
enabled true/false false
behind-proxy true/false false
add-response-header true/false false
key-prefix string ${spring.application.name:rate-limit-application}
repository CONSUL, REDIS, JPA, BUCKET4J_JCACHE, BUCKET4J_HAZELCAST, BUCKET4J_INFINISPAN, BUCKET4J_IGNITE -
default-policy-list list-of-policy -
policy-list Map of Lists of Policy -
postFilterOrder int FilterConstants.SEND_RESPONSE_FILTER_ORDER - 10
preFilterOrder int FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER

policy的相关属性

属性名 默认值
limit number of calls -
quota time of calls -
refresh-interval seconds 60
type [ORIGIN, USER, URL, ROLE] []

4、发生错误如何处理

  @Bean
  public RateLimiterErrorHandler rateLimitErrorHandler() {
    return new DefaultRateLimiterErrorHandler() {
        @Override
        public void handleSaveError(String key, Exception e) {
            // custom code
        }

        @Override
        public void handleFetchError(String key, Exception e) {
            // custom code
        }

        @Override
        public void handleError(String msg, Exception e) {
            // custom code
        }
    }
  }

二、搭建Zuul结合Ratelimit服务

1、导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>2.2.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、启动类标注解

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulRatelimitApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulRatelimitApplication.class, args);
    }
}

3、配置文件

server:
  port: 8080
spring:
  application:
    name: zuul-ratelimit
  redis:
    host: localhost
    password: 
zuul:
  # 配置路由
  routes:
    demo:
      path: /demo/**
      serviceId: demo
  # 配置限流
  ratelimit:
    enabled: true
    # 对应存储类型(用来统计存储统计信息)
    repository: redis
    # 配置路由的策略
    policy-list:
      demo:
        # 每秒允许多少个请求
        - limit: 2
          # 刷新时间(单位秒)
          refresh-interval: 1
          # 根据什么统计
          type:
            - url

4、启动后进行访问

由于我们配置的是一秒只允许两个请求,当我们超过时,会抛出过多请求异常

error

到此本文就结束啦,更多相关知识可以前往:spring-cloud-zuul-ratelimit,本demo地址:SpringCloud-Demo

猜你喜欢

转载自yq.aliyun.com/articles/707059