Skip to content

Latest commit

 

History

History
84 lines (72 loc) · 3.35 KB

script.md

File metadata and controls

84 lines (72 loc) · 3.35 KB

限流key可以与业务对象绑定也可以不与业务对象绑定。
如果key是一个普通的字符串,则表示不与对象绑定。
如果key是一个表达式字符串,例如,Spel表达式,Ognl表达式等,则表示该限流key与业务对象绑定。下面两个例子。

不与对象绑定的限流key

@RateLimit({@RateLimitKey(key ="xxxxLimitKey",clazz=XxxxLimitResponse.class)})
    public ApiResponse<Record> getXxxxApiResponse(ApiRequest request){
        //业务代码
        ......
    }

key为xxxxLimitKey。此时,就表示该限流key不与业务对象绑定。是一个全局限流的策略 此时,配置中心的配置示例:
Property Key :xxxxxLimitKey
Property Value: 200,1,220

与业务对象绑定的限流key

@RateLimit({@RateLimitKey(key ="'RateLimitByUserId:'+#args[0].userId",clazz=XxxxLimitResponse.class)})
    public ApiResponse<Record> getXxxxApiResponse(ApiRequest request){
        //业务代码
        ......
    }

key为 'RateLimitByUserId:'+#args[0].userId 实际上是一个Spring的Spel表达式。'RateLimitByUserId:'是这个表达式的前缀(注意单引号)。 +#args[0].userId表示的是使用第一个入参的userId字段做变量

此种方式就能实现基于用户id,基于ip等各种维度的与业务对象相关的限流。
此时,配置中心的配置是配置一个表达式前缀,示例spel表达式注意单引号!:
Property Key :'RateLimitByUserId:'
Property Value: 200,1,220

一个函数的多限流策略支持

    @RateLimit({@RateLimitKey(key ="'RateLimitByUserId:'+#args[0].userId",clazz=A.class),@RateLimitKey(key ="xxxxLimitKey",clazz=B.class)})
      public ApiResponse<Record> getXxxxApiResponse(ApiRequest request){
          //业务代码
          ......
      }

一个函数支持多个限流策略key的绑定。配置方式如上。

自定义表达式解析器

项目默认的表达式解析器是Spring的Spel解析器。
如需自定义自己的解析器。请自行实现com.ruubypay.ratelimit.script.AbstractScriptParser的接口进行扩展。
并通过以下的配置方式注册自己的表达式解析器。script-parser标签

   
        <!-- 
            config-group-ref 是限流配置组的引用。
            例如。配置了<config:group id="limitGroup" node="rate-limit" />
            代表配置中心有一个rate-limit分组存放限流策略的配置。该组配置的限流策略可以动态加载,实时生效
         -->
        <ratelimit:handler config-group-ref="limitGroup" script-parser="myScriptParser"/>
        

实现三个方法

    /**
     * 解析目标表达式
     * @param expressKey 表达式key
     * @param target 目标实例
     * @param arguments 参数
     * @return 返回解析结果
     */
    String getExpressValue(String expressKey, Object target, Object[] arguments);

    /**
     * 是否是满足条件的表达式(是,代表是一个可解析的表达式,否,代表是一个普通字符串)
     * @param script 表达式
     * @return 返回布尔值
     */
    boolean isScript(String script);

    /**
     * 获取前缀
     * @param script 表达式
     * @return 返回表达式前缀,排除变量部分。
     */
    String getPrefix(String script);