前提: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来实现异步接口请求的调用,减少接口请求数据的响应时间,提升用户体验。
最后
以上就是畅快钢笔最近收集整理的关于一个接口需要查询多个系统数据的性能优化的全部内容,更多相关一个接口需要查询多个系统数据内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复