@Async执行多线程发送请求并监听请求

场景:测试反应接口请求时比较慢,原因是因为第三方接口限制了请求时间为1天,但是接到的需要支持7天的查询。

问题:单线程 例如查询  2022-03-01 至 2022-03-07  ,

           1.把时间段拆成数组["2022-03-01","2022-03-02",...."2022-03-07"]

           2.使用httpclien.get("2022-03-01 00:00:00","2022-03-01 23:59:59")  for循环依次查询到7号

           3.合并结果集

这样执行下来2.4W个轨迹点用了2.77s

解决及优化思路:   给成多线程

          1.把时间段拆成数组["2022-03-01","2022-03-02",...."2022-03-07"]

          2.将每一天执行的httpclien视为一个Future,并放到数组中占位,这样可以保证数据的返回的顺序。

          3. 返回值放入 Future ,合并结果集

这样执行下来2.4W个轨迹点用了1.5s

具体实现:

1.配置线程池参数 为XXXExecutor

fleet_executor:
  # 核心线程数:线程池创建时候初始化的线程数
  corePoolSize: 10
  # 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
  maxPoolSize:  20
  # 缓冲队列:用来缓冲执行任务的队列
  queueCapacity:  500
  # 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
  keepAliveSeconds: 60

 

2.@Async("XXXExecutor")修饰消费类

@Slf4j
@Service
public class CallServiceImpl implements CallService {

    @Value("${fms-http.tsp.ip}")
    private String ipAdd;
    @Value("${fms-http.tsp.token}")
    private String token;
    @Value("${fms-http.tsp.http}")
    private String http;


    @Override
    // 指定使用beanname为callTspExecutor的线程池
    @Async("FleetExecutor")
    public Future<String> tspByKeyAsync(String apiKey, Map<String, String> params) {
        String url = ApiList.getFotonAPIConfig(apiKey);
        String rqUrl = String.format("%s://%s%s?token=%s", http, ipAdd, url, token);
        try {
            return new AsyncResult<>(HttpClientUtils.get(rqUrl, params, null));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return new AsyncResult<>("{\"type\" : \"error\",\"success\" : \"false\",\"content\" : \"读取异常!\"}");
        }
    }

}

调用方

@Override
    public List<CarLineDetailVo> getTspHisLocationsV2(String vin, Date startDate, Date endDate) throws Exception {
        List<Future<String>> futures = Lists.newArrayList();
        List<CarLineDetailVo> voList = Lists.newArrayList();
        List<Pair<Date, Date>> list = DateUtils.partitionByDay(startDate, endDate, 1);
        for (Pair<Date, Date> pair : list) {
            String startTime = DateUtils.toString(pair.getKey(), DateUtils.DEFAULT_DATE_TIME_FORMAT);
            String endTime = DateUtils.toString(pair.getValue(), DateUtils.DEFAULT_DATE_TIME_FORMAT);
            futures.add(callService.tspByKeyAsync(ApiList.CAR_HIS_LOCATION_INFO, ImmutableMap.of("idCode", vin, "startDate", startTime, "endDate", endTime)));
        }

        for (Future<String> future : futures) {
            String jsonStr = future.get();
            JSONObject rep = JSONObject.parseObject(jsonStr);
            try {
                isValid(rep);
            } catch (Exception e) {
                continue;
            }
            JSONArray arrData = rep.getJSONArray("data");
            voList.addAll(arrData.toJavaList(CarLineDetailVo.class));
        }
        return voList;
    }

3.合并结果(按需而定)

...

 

 

          

posted @ 2022-03-08 14:07  蔡徐坤1987  阅读(245)  评论(0编辑  收藏  举报