一个接口需要查询多个系统数据的性能优化

前提:java中一个接口的实现如果是基于组装多个不同系统之间的数据(并且多个系统之间数据的获取没有关联性),那么此时就可以通过异步请求的方式来实现性能优化。

实现性能优化原理剖析:

例如实现一个接口需要调用3个系统的数据,a系统的请求时间为1s,b系统的请求时间为2s,c系统的请求时间为3s,那么使用单线程完成一次接口调用的总时间至少为1+2+3=6s。使用多线程异步调用接口的时间大约为c系统请求的最长时间3s。

java中的具体实现:

需求:根据事业部门人数数量和营业部部门人数数量分别获取事业部门的系数和营业部门的系数,而获取事业部门系数和营业部门系数分别调用两个接口,具体实现如下:

@Service
public class EmpInfoServiceImpl implements EmpInfoService {

    private static Logger logger = LoggerFactory.getLogger(EmpInfoServiceImpl.class);
    ExecutorService executor = Executors.newCachedThreadPool();

    @Autowired (required = false)
    private OrgService orgService;

    @Autowired

    private EmpService empService;

    @Autowired
    private AreaRatioService areaRatioService;

    @Autowired
    private SalesOfficeRatioDao salesOfficeRatioDao;

    @Override
    public EmpInfo getEmpAscriptionByCode(String code) {
        EmpInfo empInfo = new EmpInfo();
        BaseResult<OrgRegionDeptTeam> result = orgService.getEmpORDTInfoByCode(code);
        if(BaseResult.success().getStatus().equals(result.getStatus())){//获取请求成功
            OrgRegionDeptTeam orgRegionDeptTeam = result.getData();
            //设置大区信息
            empInfo.setAreaCode(orgRegionDeptTeam.getRegionCode());
            empInfo.setAreaName(orgRegionDeptTeam.getRegionName());
            empInfo.setAreaPersonCode(orgRegionDeptTeam.getRegionLeaderCode());
            if(StringUtils.isNotBlank(empInfo.getAreaCode())){
                AreaRatio areaRatio = new AreaRatio();
                areaRatio.setCode(empInfo.getAreaCode());
                areaRatio.setArea(empInfo.getAreaName());
                AreaRatio area = areaRatioService.findOne(areaRatio);
                if(area != null) {
                    empInfo.setAreaRatio(new BigDecimal(area.getRatio()));
                }else{
                    empInfo.setAreaRatio(null);
                }
            }
            empInfo.setAreaPersonName(orgRegionDeptTeam.getRegionLeaderName());
            //设置事业部信息
            empInfo.setBusinessUnitCode(orgRegionDeptTeam.getDivisionCode());
            empInfo.setBusinessUnitName(orgRegionDeptTeam.getDivisionName());
            empInfo.setBusinessUnitPersonCode(orgRegionDeptTeam.getDivisionLeaderCode());
            empInfo.setBusinessUnitPersonName(orgRegionDeptTeam.getDivisionLeaderName());

            //设置营业部信息
            empInfo.setSalesOfficeCode(orgRegionDeptTeam.getDeptCode());
            empInfo.setSalesOfficeName(orgRegionDeptTeam.getDeptName());
            empInfo.setSalesOfficePersonCode(orgRegionDeptTeam.getDeptLeaderCode());

            empInfo.setSalesOfficePersonName(orgRegionDeptTeam.getDeptLeaderName());
            //设置团队信息
            empInfo.setTeamCode(orgRegionDeptTeam.getTeamCode());
            empInfo.setTeamName(orgRegionDeptTeam.getTeamName());
            empInfo.setPersonCode(orgRegionDeptTeam.getCode());
            //根据事业部人数数量获取部门系数
            FutureTask<BigDecimal> businessUnitFutureTask =null;
            if(StringUtils.isNotBlank(empInfo.getBusinessUnitCode())){
                businessUnitFutureTask = new FutureTask<BigDecimal>(new Callable<BigDecimal>() {
                    @Override
                    public BigDecimal call() throws Exception {
                        Integer personNum = empService.getDeptAndSubDeptUserCount(empInfo.getBusinessUnitCode());
                        return salesOfficeRatioDao.selectRatioByCountAndType(SalesOfficeRatio.BUSINESS_DEPT_TYPE,personNum);
                    }
                });
                executor.submit(businessUnitFutureTask);
            }
//            根据营业部人数数量获取部门系数
            FutureTask<BigDecimal> salesOfficeFutureTask =null;
            if(StringUtils.isNotBlank(empInfo.getSalesOfficeCode())){
                salesOfficeFutureTask = new FutureTask<BigDecimal>(new Callable<BigDecimal>() {
                    @Override
                    public BigDecimal call() throws Exception {
                        Integer personNum = empService.getDeptAndSubDeptUserCount(empInfo.getSalesOfficeCode());
                        return salesOfficeRatioDao.selectRatioByCountAndType(SalesOfficeRatio.SALEOFFICE_DEPT_TYPE,personNum);
                    }
                });
                executor.submit(salesOfficeFutureTask);
            }
            BigDecimal businessUnitRation = null;
            BigDecimal salesOfficeRation = null;
            try {
                businessUnitRation = businessUnitFutureTask.get();
                salesOfficeRation = salesOfficeFutureTask.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            empInfo.setSalesOfficeRatio(salesOfficeRation);
            empInfo.setBusinessUnitRatio(businessUnitRation!=null?businessUnitRation.toString():null);
            return empInfo;
        }else{
            return null;
        }
    }

}

总结:通过Executors生成的线程池、Callable和FutureTask来实现异步接口请求的调用,减少接口请求数据的响应时间,提升用户体验。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值