项目概要:
对外提供一个查询接口。内部先调用其他9个接口获取数据,将json数据转换相应的BOM报文调用webService接口获取的结果返回给外部调用者。
技术架构:
1. 接口查询器
定义通用数据查询抽象类,包含如下抽象方法:
execute() —处理接口查询业务逻辑
getTimeOut() —超时处理
validator() —参数校验
preprocess() —数据预处理
…..定义9个接口查询器,实现公共查询器中的抽象方法。
定义并行查询器、串行查询器
由于部分查询器之间有数据依赖,查询器的入参可能包含其他查询器的返回结果。
因此根据查询器之间的依赖关系,分组串行执行。
同时为了提高接口性能,组内的查询器并行执行。封装串行查询器SerialDataQuerier和并行查询器ParallelDataQuerier
List<IDataQuerier> serialList = new ArrayList<IDataQuerier>();
List<IDataQuerier> parallelList = new ArrayList<IDataQuerier>();
parallelList.add(Querier01);
parallelList.add(Querier02);
parallelList.add(Querier03);
ParallelDataQuerier parallelQuerier = new ParallelDataQuerier(parallelList);
parallelQuerier.setExecutorService(getExecutorService(1));//给并行查询器分配一个线程池
serialList.add(parallelQuerier);
parallelList = new ArrayList<IDataQuerier>();
parallelList.add(Querier04);
parallelList.add(Querier05);
parallelList.add(Querier06);
parallelQuerier = new ParallelDataQuerier(parallelList);
parallelQuerier.setExecutorService(getExecutorService(2));
serialList.add(parallelQuerier);
parallelList = new ArrayList<IDataQuerier>();
parallelList.add(Querier07);
parallelList.add(Querier08);
parallelList.add(Querier09);
parallelQuerier = new ParallelDataQuerier(parallelList);
parallelQuerier.setExecutorService(getExecutorService(3));
serialList.add(parallelQuerier);
serialDataQuerier = new SerialDataQuerier(serialList);
- 串行查询器
public void setExecutorService(ExecutorService executor) {
if (executor == null) throw new IllegalArgumentException("入参错误,线程执行器为空。");
this.executor = executor;
}
@Override
public Map<String, Object> query(Map<String, Object> param) throws QuerierException {
CompletionService<Map<String, Object>> service = new ExecutorCompletionService<Map<String, Object>>(executor);
for (IDataQuerier dataQuerier : querierList)
service.submit(new QuerierExecutor(dataQuerier, param));
for (int i=0; i<querierList.size(); i++)
collectedData.putAll(getCallableResult(service));
return collectedData;
}
- 并行查询器
@Override
public Map<String, Object> query(Map<String, Object> param) throws QuerierException {
Map<String, Object> collectedData = new HashMap<String, Object>(param);
for (IDataQuerier dataQuerier : querierList)
collectedData.putAll(dataQuerier.query(collectedData));
return collectedData;
}
2.工作队列
项目启动创建Bean的时候,查询数据库中配置的所有工作队列名称、线程池参数(最大线程数、主线程数等) ,初始化为一个单例模式的Map
ConcurrentHashMap<String, ThreadPoolExecutor>` executor
当出现需要多线程、异步处理的场景时根据工作队列名称去获取对应的线程池。
接口并发查询处理
使用ExecutorCompletionService任务的提交和执行都是委托给Executor来完成。
CompletionService<Map<String, Object>> service = new ExecutorCompletionService<Map<String, Object>>(executor);
for (IDataQuerier dataQuerier : querierList)
service.submit(new QuerierExecutor(dataQuerier, param));
for (int i=0; i<querierList.size(); i++)
collectedData.putAll(getCallableResult(service));