关于循环:循环请求报204问题分析

42次阅读

共计 1385 个字符,预计需要花费 4 分钟才能阅读完成。

背景

商家自主增加配件需要(Freemarker+JQuery前后端未分离我的项目)中,追加配件弹窗内批量复制粘贴配件会循环调用获取联想词接口,如果复制粘贴的配件名称很多(20+),只有一部分申请胜利(状态码 200)返回响应体,其余申请胜利(状态码 204)但没有返回响应体。

问题剖析

比照公布询价页、追加配件页发现这三个页面都有同样的问题,为什么循环并发调用接口会报 204 呢?跟运维、架构沟通后发现,这个问题的本源是网关层多了防爬、限流解决,因为当咱们的零碎被频繁的申请的时候,就有可能 将零碎压垮,有了网关,那么就能够在网关零碎做限流,因为所有的申请都须要先通过网关零碎能力路由到微服务中。

令牌桶算法

令牌桶算法是比拟常见的限流算法之一,大略形容如下:

1)所有的申请在解决之前都须要拿到一个可用的令牌才会被解决;

2)依据限流大小,设置依照肯定的速率往桶里增加令牌;

3)桶设置最大的搁置令牌限度,当桶满时、新增加的令牌就被抛弃或者回绝;

4)申请达到后首先要获取令牌桶中的令牌,拿着令牌才能够进行其余的业务逻辑,解决完业务逻辑之后,将令牌间接删除;

5)令牌桶有最低限额,当桶中的令牌达到最低限额的时候,申请解决完之后将不会删除令牌,以此保障足够的限流

如下图:

cass-webagent 网关我的项目中,限流配置如下:

icec:
  limiter:
    enabled: true
    pathConfig:
      burstCapacity: 10 #令牌桶的容量,同一个地址容许在一秒钟内实现的最大申请数
      replenishRate: 5 #容许用户每秒解决多少个申请
    routeConfig:
      burstCapacity: 50 #令牌桶的容量,同一个服务容许在一秒钟内实现的最大申请数
      replenishRate: 20 #容许用户每秒解决多少个申请
    customConfigs: #自定义令牌桶的容量
    - name: "path:/agentBuy/decodePartNo"
      config.burstCapacity: 500
    - name: "path:/agentBuy/getFastOEMore"
      config.burstCapacity: 500
    - name: "path:/maindata/llq/getDitchPriceSingle"
      config.burstCapacity: 100
    #- name: "route:web-market"
    #  config.burstCapacity: 51

当用户一秒内申请数量超过 20 个时,可能有一部分申请返回 204(no content

解决方案

1、前端管制每秒的申请并发数

比方,每个一个时间段发送一定量级的申请,利用一个伪死循环阻塞主线程

// 第一种,应用 while 循环
function sleep(delay) {var start = (new Date()).getTime();
    while((new Date()).getTime() - start < delay) {continue;}
}

// 或者应用 for 循环
function sleep(delay) {for(var t = Date.now(); Date.now() - t <= d;);
}

2、在网关减少自定义某些接口门路容许用户每秒解决的申请量

3、将循环调用改成批量接口,这才是最彻底的解决方案

总结

本文仅仅是这类问题做一个剖析记录,在开发中咱们要防止这种循环调用接口的场景。

正文完
 0