遥以寄北 2020-08-14 17:11 采纳率: 0%
浏览 676

如何利用线程池解决调用第三接口出现 429 too many requests问题?

做报表统计的时候,需要调用一个第三方接口根据IP或许该IP的实际地址。
我先写了一个接口,从数据库中取出每条的ip 再调用第三方接口进行查询,把查到的地址信息存入数据库。
测试的时候出现429 too many requests问题,于是按照同事的建议做了些优化,并添加了线程池,最后测试的时候,没有出现因为 429 too many requests 问题而直接报500的错,但是 更新数据库中的数据1500条数据,一共花了一个小时,控制台打印显示大概是,每更新二三十条数据(调用二三十次第三方接口)它就会因为
频繁请求等问题而停顿,尝试再次发起请求。



我主要想问的就是:



如何利用线程池解决调用第三接口出现 429 too many requests的问题



或者



不使用线程池的话有没有其他方法可以解决这个问题



第三方接口: http://ip-api.com/json/ip地址?lang=zh-CN



下面是线程池相关部分的代码

 RejectedExecutionHandler handler = new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                if(!executor.isShutdown()){
                    try{
                        executor.getQueue().put(r);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        };
//线程池
        ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 50, 30*1000,TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(1000),handler);

for (ModuleQueryLogEntity moduleQueryLogEntity : moduleQueryLogDtos){
            pool.execute(() -> {
                try {
                    ModuleQueryUrlResponse response = new ModuleQueryUrlResponse();
                                        //传入ip地址调用第三方接口查询
                    response = getUrlResponse(moduleQueryLogEntity.getIp(), ModuleQueryUrlResponse.class);
                                        //如果查询成功,把查到的信息存入数据库
                    if(response.getStatus().equals(SUCCESS)){
                        moduleQueryLogEntity.setCity(response.getCity());
                        moduleQueryLogEntity.setCountry(response.getCountry());
                        moduleQueryLogRepository.save(moduleQueryLogEntity);
                    }
                                        //沉睡
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

//下面是调用第三方接口的代码
public <T> T getUrlResponse(String ip,Class<T> responseType){
        HttpHeaders headers = new HttpHeaders();
        headers.add("Retry-After","100");
        StringBuilder url = new StringBuilder(FINE_IP);
        url.append(ip);
        url.append("?lang=zh-CN");
        log.info(url.toString());
        ResponseEntity<String> response = restTemplate.exchange(
                url.toString(),
                HttpMethod.GET,
                new HttpEntity<String>(headers),
                String.class);
        return JSON.parseObject(response.getBody(), responseType);
    }


  • 写回答

3条回答 默认 最新

  • threenewbee 2020-08-14 17:28
    关注

    要么服务器性能不行,要么服务器做了限制。你应该让服务器的开发者提供一个可以批量操作的接口,一条一条肯定慢了。

    评论

报告相同问题?

悬赏问题

  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办