zoukankan      html  css  js  c++  java
  • QPS

    接口限流预案

    一、限流前提

    限制资源使用速率,在互联网中一般是:

    限制请求总量(秒杀)或某段时间内请求总量(攻击/服务资源有限)

    1. 访问耗时
      接口响应速度

      时间 描述
      <500ms
      >1.5s 慢(优化)
      >3s
    2. 访问频次

      名词 含义
      QPS 每秒查询
      TPS 每秒事务
      RT 响应时间
      PV 一次刷新或一次请求
      并发数 系统同时能处理的请求数量
      吞吐量 单个request 对CPU消耗越高,外部系统接口、IO速度越慢,系统吞吐能力越低,反之越高

      公式:按二八定律来看,如果每天 80% 的访问集中在 20% 的时间里,这 20% 时间就叫做峰值时间。

      • QPS(TPS)= 并发数/平均响应时间
      • 并发数 = QPS*平均响应时间
      • ( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)
      • 峰值时间每秒QPS / 单台机器的QPS = 需要的机器
    3. 实施方法

      • 先通过JMeter测出接口的 QPS
      • 根据接口请求数统计算出 峰值QPS

      峰值QPS>QPS 可能就需要限流

    二、限流方式

    1. 接口内部限制线程数

      private readonly static Semaphore _semaphore = new Semaphore(4, 8);
      try
      {
          _semaphore.WaitOne();
          // Do Something
      }
      finally
      {
          _semaphore.Release();
      }
      

      这种只是限制并发的线程数,外部请求是处于等待状态,最终都会返回,除非客户端超时处理。

    2. IP同源限流

      借助AspNetCoreRateLimit中间件实现IP同源限流,先安装中间件

      Install-Package AspNetCoreRateLimit
      Install-Package Microsoft.Extensions.Caching.Redis // Redis分布式缓存
      
      services.AddDistributedRedisCache(options =>
          {
              options.Configuration = "127.0.0.1:6379,password=123456,connectTimeout=5000,syncTimeout=10000";
              options.InstanceName = "WebRatelimit";
          });
      //从appsettings.json获取相应配置
      services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
      //注入计数器和规则存储
      services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();
      services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>();
      services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
      //配置(计数器密钥生成器)
      services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
      
      //启用限流,需在UseMvc前面
      app.UseIpRateLimiting();
      
    3. Nginx限流

      • 限制访问频率

        Nginx中使用ngx_http_limit_req_module模块来限制的访问频率

        http {
            limit_req_zone $binary_remote_addr zone=myLimit:10m rate=5r/s;
        }
        
        server{
            location / {
                limit_req zone=myLimit burst=5 nodelay;
                rewrite / http://www.xxx.com permanent;
            }
        }
        

        上面binary_remote_addr就是key,表示基于客户端ip(remote_addr)进行限流,binary_表示压缩内存占用量。定义了一个大小为10M,名称为myLimit的内存区,用于存储IP地址访问信息。rate设置IP访问频率,rate=5r/s表示每秒只能处理每个IP地址的5个请求。Nginx限流是按照毫秒级为单位的,也就是说1秒处理5个请求会变成每200ms只处理一个请求。如果200ms内已经处理完1个请求,但是还是有有新的请求到达,这时候Nginx就会拒绝处理该请求。burst=5 nodelay,如果没有添加nodelay参数,则可以理解为预先在内存中占用了5个请求的位置,如果有5个突发请求就会按照200ms去依次处理请求,也就是1s内把5个请求全部处理完毕。如果1s内有新的请求到达也不会立即进行处理,因为紧急程度更低。这样实际上就会将额外的5个突发请求以200ms/个去依次处理,保证了处理速率的稳定,所以在处理突发流量的时候也一样可以正常处理。如果添加了nodelay参数则表示要立即处理这5个突发请求。

      • 限制并发连接数

        Nginx中的ngx_http_limit_conn_module模块提供了限制并发连接数的功能

        http {
            limit_conn_zone $binary_remote_addr zone=myip:10m;
            limit_conn_zone $server_name zone=myServerName:10m;
        }
        
        server{
            location / {
                limit_conn myip 10;
                limit_conn myServerName 100;
                rewrite / http://www.xxx.com permanent;
            }
        }
        

        上面配置了单个IP同时并发连接数最多只能10个连接,并且设置了整个虚拟服务器同时最大并发数最多只能100个链接。当然,只有当请求的header被服务器处理后,虚拟服务器的连接数才会计数。刚才有提到过Nginx是基于漏桶算法原理实现的,实际上限流一般都是基于漏桶算法令牌桶算法实现的。

    4. RabbitMq限流/消峰

      如秒杀场景,有50000份,根据RabbitMq限制接受6000/8000请求,其他拒绝。

    三、实施计划

    1. 目前采用第二种方案,原因:

      第一种用户交互会不太友好,当访问量满的时候,后面的用户需要持续等待直至超时;
      第三种需要运维配置,没有自己配置灵活;
      第四种一般用于限流消峰处理。

    2. 测试监听限流配置(11-10)

      通过监听配置文件,限制接口频次,不用重启应用

    3. 找出需要限流的接口(11-11)

      • 统计访问量前十接口
      • 统计响应慢前十接口
    4. 测出合适限流频次(11-12/13)

      灰度环境测试这些接口的吞吐量,然后设定限流频次

    四、实施

    1. 配置初始化时加载,无法动态配置,修改配置后还需重启。

    2. 接口统计

      • 高流量接口

        url rate count
        /api/services/app/BasicSet/GetBasicsetThemecolor 5.38% 2,098,111
        /api/TokenAuth/AuthenticateMobile 5.32% 2,074,173
        /api/services/app/SuspendedWindow/GetSuspendedWindowResp 4.11% 1,603,795
        /promotion/offer-service/app/activity/getMeetGiftList 3.96% 1,545,701
        /promotion/offer-service/app/activity/getActivityProductList 3.91% 1,523,793
        /promotion/offer-service/app/activity/getBatchActivityProductStock 3.87% 1,508,272
        /api/services/app/Advertise/GetInfo 3.72% 1,451,478
        /api/services/app/VipInfo/GetBasicSetDto 3.27% 1,277,221
        /OperAtion/t?operation=viptypesyncnew 2.86% 1,116,057
        /api/TokenAuth/IsRefresh 2.66% 1,037,517
      • 响应耗时

        request_time rate count
        0.01600000075995922 13.79% 290,258
        0.004000000189989805 11.20% 235,863
        0.017000000923871994 9.97% 209,867
        0.014999999664723873 8.97% 188,790
        0.003000000026077032 7.62% 160,481
        0.017999999225139618 5.97% 125,772
        0.014000000432133675 5.00% 105,281
        0.01899999938905239 4.10% 86,272
        0.007000000216066837 3.30% 69,393
        0.004999999888241291 2.78% 58,457

        响应都很快了

    3. 灰度测试

      频繁访问前十接口QPS测试

      url rate count 峰值QPS QPS T-QPS1 T-QPS2 T-QPS3
      /api/services/app/BasicSet/GetBasicsetThemecolor 5.38% 2,098,111 97.13476852 82.6 40.9 41.6 47.1
      /api/TokenAuth/AuthenticateMobile 5.32% 2,074,173 96.02652778 49.2 50.9 51
      /api/services/app/SuspendedWindow/GetSuspendedWindowResp 4.11% 1,603,795 74.24976852 71.9 118.6 186
      /promotion/offer-service/app/activity/getMeetGiftList 3.96% 1,545,701 71.56023148
      /promotion/offer-service/app/activity/getActivityProductList 3.91% 1,523,793 70.54597222
      /promotion/offer-service/app/activity/getBatchActivityProductStock 3.87% 1,508,272 69.82740741
      /api/services/app/Advertise/GetInfo 3.72% 1,451,478 67.19805556 178.3 175.1 184.3
      /api/services/app/VipInfo/GetBasicSetDto 3.27% 1,277,221 59.13060185 26.9 12.6 12.5
      /OperAtion/t?operation=viptypesyncnew 2.86% 1,116,057 51.66930556 40.2 83 56.8
      /api/TokenAuth/IsRefresh 2.66% 1,037,517 48.03319444 125.9 125.8 117.2
    4. 限流建议

  • 相关阅读:
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十四):权限控制(Shiro 注解)
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十三):配置中心(Config、Bus)
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十二):链路追踪(Sleuth、Zipkin)
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十一):服务网关(Zuul)
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十):服务熔断(Hystrix、Turbine)
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十九):服务消费(Ribbon、Feign)
    Spring Boot + Mybatis 实现动态数据源
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十八):注册中心(Spring Cloud Consul)
    Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十七):登录验证码实现(Captcha)
    Spring Boot + Spring Cloud 构建微服务系统(十):配置中心(Spring Cloud Bus)
  • 原文地址:https://www.cnblogs.com/Nine4Cool/p/13959662.html
Copyright © 2011-2022 走看看