我是靠谱客的博主 畅快钢笔,最近开发中收集的这篇文章主要介绍一个接口需要查询多个系统数据的性能优化,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前提: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来实现异步接口请求的调用,减少接口请求数据的响应时间,提升用户体验。

最后

以上就是畅快钢笔为你收集整理的一个接口需要查询多个系统数据的性能优化的全部内容,希望文章能够帮你解决一个接口需要查询多个系统数据的性能优化所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部