单机限流

什么是单机限流

单机限流是一种通过统计单机QPS指标,当达到规则指定阈值时对流量进行限制,保障服务实例不被瞬时流量给冲垮。

限流规则说明

北极星支持在界面配置单机限流规则,通过以下路径可以打开限流规则的编辑页面:控制台->服务列表->具体服务->限流规则->新建,打开后,规则各配置项说明如下:

单机限流 - 图1

接口名称

可选,指定限流规则的接口过滤参数,接口名可对应方法名、http url等信息,不填代表不过滤。

  • 接口:规则生效所对应的接口名,用于匹配客户端传入的method参数,默认为空(全部)
  • 匹配方式:接口字段的匹配方式,支持全匹配、不等于、包含、不包含、正则表达式四种匹配模式

请求匹配规则

可选,指定限流规则的请求参数匹配条件,不填代表不过滤,支持以下四种参数类型:

  • 自定义参数:自定义KEY和VALUE,具体的请求参数值可通过SDK进行传入。

  • 请求头(HEADER):针对协议消息头(http header/grpc header)进行过滤。

  • 请求参数(QUERY):针对协议请求参数(http query)进行过滤。

  • 方法(METHOD):针对协议的METHOD(http method/grpc method)进行过滤。

  • 主调服务:针对微服务调用场景下,主调方的服务名进行过滤。

  • 主调IP:针对主调方机器的IP地址进行过滤。

每种类型参数值支持以下几种值匹配模式:

  • 全匹配:全值匹配,传入的值与配置的值相同才匹配通过。

  • 正则表达式:用户配置正则表达式,通过正则表达式对传入的值进行匹配,正则表达式支持Google RE2标准单机限流 - 图2 (opens new window)

  • 不等于:取反匹配,传入的值与所配置的值不相等才算匹配成功。

  • 包含:多字符串取OR匹配,传入的值只要匹配到其中一个字符串,就算匹配成功。字符串之间使用逗号进行分割。值格式为’value1,value2,value3‘,匹配到其中一个就算成功。

  • 不包含:多字符串取反匹配,传入的值必须都没有出现在所配置的字符串列表中,才算匹配通过。值格式为’value1,value2,value3‘,全部不等于才算成功。

限流阈值

指定统计周期内的统计阈值,达到阈值则进行限流。可以配置多个限流阈值,多个限流阈值可同时生效,任意触发了一个就进行限流。

  • 统计时长:限流阈值的统计时长,单位秒,默认为1秒
  • 请求数:达到限流条件的请求数阈值。默认为1

限流效果

限流阈值被触发后,如何进行对流量进行限制,目前支持2种模式(默认为直接拒绝):

  • 直接拒绝:当统计时长内请求数达到阈值,后续新的请求会被拒绝,直到下个统计周期到来才恢复。
  • 匀速排队:基于漏桶算法,将请求数平均分配到统计时长内(细分的最小度量单位为1ms),从而控制请求以均匀的速度通过。

如何使用

北极星限流支持多语言SDK、以及集成了SDK的生态框架(如Spring Cloud, gRPC等)接入,下面以Java SDK为例进行演示具体使用过程。

演示场景中, 被调服务名叫RateLimitServiceJava,命名空间为default,用户真正使用时,可以按照自己的需要使用其他服务名。

具体代码的样例可以参考:单机限流demo单机限流 - 图3 (opens new window)

针对服务进行限流

  1. 配置限流规则

在RateLimitServiceJava服务下新建限流规则,指定QPS为10,限流效果选择直接拒绝。

单机限流 - 图4

  1. 使用北极星Java SDK执行限流API

关键代码:

  1. //构造请求,获取限流配额
  2. QuotaRequest quotaRequest = new QuotaRequest();
  3. quotaRequest.setNamespace(NAMESPACE_DEFAULT);
  4. quotaRequest.setService(ECHO_SERVICE_NAME);
  5. quotaRequest.setCount(1);
  6. QuotaResponse quotaResponse = limitAPI.getQuota(quotaRequest);
  7. if (quotaResponse.getCode() == QuotaResultCode.QuotaResultOk) {
  8. // 配额允许,本次请求通过
  9. } else {
  10. // 配额已经用完,本次请求拒绝
  11. }

针对接口+标签进行细粒度限流

  1. 配置限流规则

在RateLimitServiceJava服务下新建限流规则,指定QPS为10,方法名为/echo,标签键为user,值为foo,限流效果选择直接拒绝。

单机限流 - 图5

  1. 使用北极星Java SDK执行限流API

关键代码:

  1. QuotaRequest quotaRequest = new QuotaRequest();
  2. quotaRequest.setNamespace(NAMESPACE_DEFAULT);
  3. quotaRequest.setService(ECHO_SERVICE_NAME);
  4. quotaRequest.setMethod("/echo");
  5. quotaRequest.setLabels(parameters);
  6. quotaRequest.setCount(1);
  7. QuotaResponse quotaResponse = limitAPI.getQuota(quotaRequest);
  8. if (quotaResponse.getCode() == QuotaResultCode.QuotaResultOk) {
  9. // 配额允许,本次请求通过
  10. } else {
  11. // 配额已经用完,本次请求拒绝
  12. }

使用匀速排队

  1. 配置限流规则

在RateLimitServiceJava服务下新建限流规则,指定QPS为10,限流效果选择匀速排队。

单机限流 - 图6

  1. 使用北极星Java SDK执行限流API

关键代码:

  1. QuotaRequest quotaRequest = new QuotaRequest();
  2. quotaRequest.setNamespace(NAMESPACE_DEFAULT);
  3. quotaRequest.setService(ECHO_SERVICE_NAME);
  4. quotaRequest.setCount(1);
  5. QuotaResponse quotaResponse = limitAPI.getQuota(quotaRequest);
  6. if (quotaResponse.getCode() == QuotaResultCode.QuotaResultOk) {
  7. // 匀速排队等待
  8. if (quotaResponse.getWaitMs() > 0) {
  9. try {
  10. Thread.sleep(quotaResponse.getWaitMs());
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. } else {
  16. // 已经超过最大等待时长,本次请求拒绝
  17. }

其他SDK及框架接入参考