Spring Cloud security services combat micro-limiting _4-10_ do with spring-cloud-zuul-ratelimit

Limit on Benpian speak gateway stream

With open source projects spring-cloud-zuul-ratelimit  do restrictor on the gateway (project GitHub: https://github.com/marcosbarbero/  )

 

1, the gateway project, introduced maven dependent current limiting components:

 

 

 2, the gateway project yml configuration, the configuration associated with limiting

github also related configuration instructions: https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit

Limiting framework limiting need to save some of the information, there may be a database, may also be present in redis, here with redis experiment, but I think limiting the enumeration class storage component, if using a database stored limiting information, only use JPA, can not be used mybatis (crooked nuts may prefer JPA):

 

public enum RateLimitRepository {
    REDIS,
    CONSUL,
    JPA,
    BUCKET4J_JCACHE,
    BUCKET4J_HAZELCAST,
    BUCKET4J_IGNITE,
    BUCKET4J_INFINISPAN,
}

 

Limiting yml configuration:

Limiting the information, there is a period of the redis, over the period will be automatically cleared, so in order to see information about limiting the redis, where the time window is set to 10 seconds (I just started setting is 1 second, redis life and death do not see limiting information, wasting ten minutes time)

Zuul: 
  routes : # routing configuration is a Map, you can configure multiple 
    token:   # token request the end, are forwarded to http: // localhost: 9090 certification server address 
      url: HTTP: // localhost: 9090 
    order:   # end of the order the requests are forwarded to http: // localhost: 9060 Ding single service 
      url: HTTP: // localhost: 9060 
  sensitive-headers:   null   # set sensitive head is set to null, Authorization request header and other requests are forwarded back 
  ratelimit : Key -prefix: Rate 
      Enabled : to true 
      Repository : Redis
       default -policy- List :
         #
          ########### to say the following configuration: not more than two requests per one second, two time does not request more than one second (quota) ########## ## 
        - limit: 2 # optional - Refresh Request Number limit per window interval The 
          quota:. 1 # optional - Refresh Request time interval The limit per window (in seconds The) 
          Refresh interval The-: 10  # window of time (in seconds The) 
          type: # # The What controls the flow rate may be used in combination, such as url, httpmethod combination, will put / orders get and post requests handled separately 
            - URL
             - http_method
           # - # user Security support according to user control needs, (usually not) 
          # - # the Origin the client's ip control

3. Experimental 

1, respectively, the start order, certification, three gateway services

 

 

 

 2, acquired from the gateway a token:

OAuth2 password mode parameter

 

 

 Gateway client's username, password

 3, take the token access gateway to create an order

手速点的快点,Http就会返回 429 状态码,表示过多的请求。

 

 

 看redis,已经有限流的信息了:

 

生成的限流的key是: rate:order:/orders:POST        rate是配置的限流信息的前缀,order是zuul转发的规则,/orders:POST 是配置的限流类型 url 和http_method的组合

当下一个请求过来的时候就会计算key,然后根据key去redis找,看当前的key已经过了多少个请求了,来判断这次请求能不能过。

大部分情况下,根据user 、origin、 url 、http_method已经满足需求了。有些特殊的场景,需要根据传过来的参数进行限流,比如有两种优惠券A、B,优惠券A业务简单,每秒能处理100个请求,优惠券B复杂,每秒能处理10个请求,此时自带的限流规则就不能满足需求了。限流归根揭底是根据key来限流的,所以此时就要自定义key的生成规则。

自定义key的生成规则:

 

import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.RateLimitUtils;
import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.properties.RateLimitProperties;
import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.DefaultRateLimitKeyGenerator;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 自定义限流key生成规则,自定义限流规则
 */
@Component
public class MyKeyGen extends DefaultRateLimitKeyGenerator {

    public MyKeyGen(RateLimitProperties properties, RateLimitUtils rateLimitUtils){
        super(properties,rateLimitUtils);
    }

    @Override
    public String key(HttpServletRequest request, Route route, RateLimitProperties.Policy policy) {
        //可以从route拿出路由信息,自定义key生成规则:https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit#usage
        return super.key(request, route, policy);
    }
}

 

重写错误处理:

 

package com.nb.security.filter;

import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.repository.DefaultRateLimiterErrorHandler;
import org.springframework.stereotype.Component;

/**
 * 限流错误自定义处理
 */
@Component
public class MyRateLimitErrorHandler extends DefaultRateLimiterErrorHandler {

    //限流数据存时候报错了的处理,一般不覆盖
    @Override
    public void handleSaveError(String key, Exception e) {
        super.handleSaveError(key, e);
    }

    //限流取数据报错的处理,一般不覆盖
    @Override
    public void handleFetchError(String key, Exception e) {
        super.handleFetchError(key, e);
    }

    //限流错误处理,记日志等
    @Override
    public void handleError(String msg, Exception e) {
        super.handleError(msg, e);
    }
}

都在网关上做限流是有问题的

 

 

1,耦合

  如上所述的根据不同的优惠券进行的限流,如果优惠券又多了种类型,就要重写网关的限流的代码,重写部署网关,这就是耦合,是不行的。服务和服务之间,以及服务和基础组件之间,一定要解耦。微服务场景下解耦是价值最大的事。一旦两个服务耦合在一块,一个变了,另一个也要跟着变。

2,限流的数量的问题

  网关只能处理从整个微服务外边进来的请求,并不处理微服务之间的调用。如,有A B两个微服务,A还调用了B服务,A、B服务每秒处理的请求最大都是100个,网关限流 A 100请求/秒   ,B 100请求/秒。此时有100个A请求到网关,100个B请求也到了网关,都通过了网关,而此时,100个到A的请求又请求了100次B,导致B服务不可用!

所以:在网关上不要做细粒度的限流,没有用,因为很多服务之间的调用,都不走网关。网关层面只根据硬件设备的处理能力做一些限流,如服务的节点用的是tomcat,根据每个tomcat的资源配置,计算能处理的多少并发请求,根据这个去限流。具体的方法,跟业务逻辑的耦合,都不要发生在网关上的限流逻辑里。这就是上边配置里说的,限流类型 user最好不在网关上用。

       

 本篇github :  https://github.com/lhy1234/springcloud-security/tree/chapt-4-10-ratelimit  如果对你有一点帮助,点个小星星吧!谢谢

Guess you like

Origin www.cnblogs.com/lihaoyang/p/12127768.html