使用CountDownLatch解决接口循环网络请求造成的耗时问题

背景:由于查询接口调用第三方平台,需要通过http请求获得设备数据,但由于第三方接口获取数据的限制,只能通过某些接口获取机柜与机房、机柜与设备关系后再查询对应设备的信息,单线程执行效果慢造成了网络io耗时较长的问题,后引入CountDownLatch计数器来解决。
接口的响应时间

使用前:使用CountDownLatch解决接口循环网络请求造成的耗时问题_第1张图片

 使用后:

使用CountDownLatch解决接口循环网络请求造成的耗时问题_第2张图片

上代码:

原来的代码(主要列出耗时代码块):

@Override
    public Result searchDeviceList(HttpServletRequest httpRequest, DeviceQuery deviceQuery) {
        String cookie = httpRequest.getHeader("Cookie");

        List jsonList = new ArrayList();
        List cabinetVoList = new ArrayList<>();

        Map cabinetMap = new HashMap<>();
        Map roomCabinetMap = new HashMap<>();
        Map result = new HashMap<>();
        try {
            //todo...

            if (cabinetCount > 0) {
                cabinetVoList = getCabinetList(cookie, CmdbConstants.CMDB_POST_CABINET_PAGE_URL, cabinetCount, cabinetVoList);

                for (int i = 0; i < cabinetVoList.size(); i++) {
                    String cabinetId = cabinetVoList.get(i).getBkInstId();
                    cabinetMap.put(cabinetId, cabinetVoList.get(i));
                    //查询机柜-机房
                    List cabinetRoomVoList = new ArrayList<>();
                    cabinetRoomVoList = geRelationList(cookie, CmdbConstants.CMDB_POST_CABINET_DATA_CENTER_DEVICE_URL, cabinetRoomVoList, 1, Integer.parseInt(cabinetId));
                    String roomId = null;
                    if (CollectionUtils.isNotEmpty(cabinetRoomVoList)) {
                        roomId = cabinetRoomVoList.get(0).getBkInstId();
                    }
                    //查询机柜-设备
                    List cabinetDeviceVoList = new ArrayList<>();
                    cabinetDeviceVoList = geRelationList(cookie, CmdbConstants.CMDB_POST_CABINET_DATA_CENTER_DEVICE_URL, cabinetDeviceVoList, 2, Integer.parseInt(cabinetId));
                    for (RoomVo roomVo : cabinetDeviceVoList) {
                        RoomCabinet roomCabinet = new RoomCabinet();
                        roomCabinet.setRoomId(roomId).setCabinetId(cabinetId);
                        roomCabinetMap.put(roomVo.getBkAsstInstId().toString(), roomCabinet);
                    }
                }
            } else {
                result.put("list", new ArrayList());
                result.put("total", 0);
                return Result.OK(result);
            }
            
	//todo...
            return Result.OK(result);
        } catch (InterruptedException e) {
            log.error("查询线程异常 !");
            return Result.error(999, "查询失败,Cookie失效!");
        } catch (BaseException e) {
            return Result.error(999, e.getMsg());
        } catch (Exception e) {
            return Result.error(999, "查询失败,Cookie失效!");
        }
    }

使用CountDownLatch后,查询接口部分:

@Override
    public Result searchDeviceList(HttpServletRequest httpRequest, DeviceQuery deviceQuery) {
        String cookie = httpRequest.getHeader("Cookie");
      
        List jsonList = new ArrayList();
        List cabinetVoList = new ArrayList<>();

        Map cabinetMap = new HashMap<>();
        Map roomCabinetMap = new HashMap<>();
        Map result = new HashMap<>();
        try {
          //todo...
            int cabinetCount = getCount(cookie, CmdbConstants.CMDB_POST_CABINET_COUNT_URL);
            CountDownLatch latch = new CountDownLatch(0);
            if (cabinetCount > 0) {
                cabinetVoList = getCabinetList(cookie, CmdbConstants.CMDB_POST_CABINET_PAGE_URL, cabinetCount, cabinetVoList);

                latch = new CountDownLatch(cabinetVoList.size());

                for (int i = 0; i < cabinetVoList.size(); i++) {
                    // 提交任务给线程池处理
                    executorConfig.asyncServiceExecutor().execute(new CabinetTask(cabinetVoList.get(i), cookie, cabinetMap, roomCabinetMap, latch,this));
                }
            } else {
                result.put("list", new ArrayList());
                result.put("total", 0);
                return Result.OK(result);
            }
            // 等待所有任务完成
            latch.await();
	//todo...
            return Result.OK(result);
        } catch (InterruptedException e) {
            log.error("查询线程异常 !");
            return Result.error(999, "查询失败,Cookie失效!");
        } catch (BaseException e) {
            return Result.error(999, e.getMsg());
        } catch (Exception e) {
            return Result.error(999, "查询失败,Cookie失效!");
        }
    }

线程执行部分:

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

public class CabinetTask implements Runnable {
    private DeviceServiceImpl deviceService;
    private CabinetVo cabinetVo;
    private String cookie;
    private Map cabinetMap;
    private Map roomCabinetMap;
    private CountDownLatch latch;

    public CabinetTask(CabinetVo cabinetVo, String cookie, Map cabinetMap,
                       Map roomCabinetMap, CountDownLatch latch, DeviceServiceImpl deviceService) {
        this.cabinetVo = cabinetVo;
        this.cookie = cookie;
        this.cabinetMap = cabinetMap;
        this.roomCabinetMap = roomCabinetMap;
        this.latch = latch;
        this.deviceService = deviceService;
    }

    @Override
    public void run() {
        String cabinetId = cabinetVo.getBkInstId();
        cabinetMap.put(cabinetId, cabinetVo);

        //查询机柜-机房
        List cabinetRoomVoList = new ArrayList<>();
        cabinetRoomVoList = deviceService.geRelationList(cookie, CmdbConstants.CMDB_POST_CABINET_DATA_CENTER_DEVICE_URL, cabinetRoomVoList, 1, Integer.parseInt(cabinetId));
        String roomId = null;
        if (CollectionUtils.isNotEmpty(cabinetRoomVoList)) {
            roomId = cabinetRoomVoList.get(0).getBkInstId();
        }

        //查询机柜-设备
        List cabinetDeviceVoList = new ArrayList<>();
        cabinetDeviceVoList = deviceService.geRelationList(cookie, CmdbConstants.CMDB_POST_CABINET_DATA_CENTER_DEVICE_URL, new ArrayList<>(), 2, Integer.parseInt(cabinetVo.getBkInstId()));

        // 对 cabinetDeviceVoList 进行后续处理
        for (RoomVo roomVo : cabinetDeviceVoList) {
            RoomCabinet roomCabinet = new RoomCabinet();
            roomCabinet.setRoomId(roomId).setCabinetId(cabinetId);
            roomCabinetMap.put(roomVo.getBkAsstInstId().toString(), roomCabinet);
        }

        // 任务完成,减少任务计数
        latch.countDown();
    }
}

 

 

 

你可能感兴趣的:(JAVA,多线程,java)