美文网首页
java B2B2C Springcloud电子商务平台源码-

java B2B2C Springcloud电子商务平台源码-

作者: IT小跑兵 | 来源:发表于2019-01-16 09:08 被阅读5次

    API限流
    微服务开发中有时需要对API做限流保护,防止网络攻击,比如做一个短信验证码API,限制客户端的请求速率能在一定程度上抵御短信轰炸攻击,降低损失。
    使用方法
    比如我们要对user-service这个服务进行限流,限制每个请求源每分钟最多只能请求10次。
    需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码 一零三八七七四六二六
    首先在项目中添加 spring-cloud-zuul-ratelimit 依赖:

    <dependency>
        <groupId>com.marcosbarbero.cloud</groupId>
        <artifactId>spring-cloud-zuul-ratelimit</artifactId>
        <version>1.5.0.RELEASE</version>
    </dependency>
    

    然后再添加如下配置即可:

    zuul:
      ratelimit:
        enabled: true
        behind-proxy: true
        policy-list:
          user-service:
            - limit: 10 
              refresh-interval: 60
              type: 
                - user
                - origin
                - url
    

    测试客户端如果60s内请求超过10次,服务端就抛出异常,一分钟后又可以正常请求

    某个IP的客户端被限流并不影响其他客户端,即API网关对每个客户端限流是相互独立的

    限流数据存储
    对API限流是基于Zuul过滤器完成的,默认情况下限流数据是记录在内存中的,实际上是用ConcurrentHashMap保存,当然也提供了多种存储方式,包括Redis、Consul、Spring Data JPA,使用这三种存储方式要添加相关依赖。

    然后再添加存储配置,比如使用Redis的配置:

    zuul:
      ratelimit:
        repository: Redis
    

    原理分析
    限流拦截时机
    限流过滤器是在请求被转发之前调用的

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

    限流类型
    限流类型主要包括url、origin、user三种

       if (types.contains(URL)) {
           joiner.add(route.getPath());
       }
       if (types.contains(ORIGIN)) {
           joiner.add(getRemoteAddr(request));
       }
       if (types.contains(USER)) {
           joiner.add(request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : ANONYMOUS);
       }
    

    url类型的限流就是通过请求路径区分

    origin是通过客户端IP地址区分

    user是通过授权用户进行区分,也包括匿名用户

    可以多个限流类型结合使用

    如果不配置限流类型,就不做以上区分

    拦截限流请求
    在过滤器的run方法中判断请求剩余次数,小于0就拦截请求:

       if (rate.getRemaining() < 0) {
           ctx.setResponseStatusCode(TOO_MANY_REQUESTS.value());
           ctx.put("rateLimitExceeded", "true");
           throw new ZuulRuntimeException(new ZuulException(TOO_MANY_REQUESTS.toString(),
                   TOO_MANY_REQUESTS.value(), null));
       }
    

    可以看到,单位时间内剩余请求次数小于0时抛出ZuulRuntimeException,直接返回客户端TOO_MANY_REQUESTS异常消息,达到拦截请求的效果。
    java B2B2C Springcloud电子商务平台源码

    相关文章

      网友评论

          本文标题:java B2B2C Springcloud电子商务平台源码-

          本文链接:https://www.haomeiwen.com/subject/wjepdqtx.html