前言
系统A调用系统B接口会被频繁多次调用,一次过来1000请求,那么意味着会调用B系统1000次,这样调用会大大降低接口效率,那么如何批量调用这个接口,同时能让返回结果对应与每个请求线程一 一对应
一、高并发接口设计
1、通常调用
通常单条请求调用如下:
public Map<String,Object> queryOrderInfo(String code){
Map<String,Object> result = remoteService.queryOrderInfoByCode(code);
return result;
}
2、批量调用
比如1000个请求,如何批量调用
1)首先需要系统B提供一个批量接口
2) 修改原接口如下:
将接口参数打包成Request对象,调用接口时添加一个阻塞队列
class Request{
private String serialNo;
private String orderCode;
private CompletableFuture future;
}
private LinkedBlockingQueue<Request> queue = new LinkedBlockingQueue<>();
public Map<String,Object> queryOrderInfo(String orderCode) throws ExecutionException, InterruptedException {
String serialNo = UUID.randomUUID().toString(); //每个请求唯一
Request request = new Request();
request.serialNo = serialNo;
request.orderCode = orderCode;
CompletableFuture<Map<String,Object>> future = new CompletableFuture<>();
request.future = future;
//将请求添加到队列
queue.add(request);
//阻塞返回,直到接口complete才返回
return future.get();
}
在@PostConstruct方法中,定时取出队列中数据,调用批量接口如下:
@PostConstruct
public void init(){
ScheduledExecutorService scheduled =
Executors.newScheduledThreadPool(1);
scheduled.scheduleAtFixedRate(()->{
int size = queue.size();
if(size == 0){
return;
}
List<Request> requests = new ArrayList<>();
for(int i = 0;i< size ;i++){
requests.add(queue.poll());
}
//组装批量接口参数
List<Map<String,String>> params = new ArrayList<>();
for(Request request : requests){
Map<String,String> map = new HashMap<>();
map.put("orderCode",request.orderCode);
map.put("serialNo",request.serialNo);
params.add(map);
}
List<Map<String,Object>> responses = remoteService.queryOrderInfoByCodeBatch(params);
HashMap<String,Map<String,Object>> responseMap = new HashMap<>();
for(Map<String,Object> response:responses){
String serialNo = response.get("serialNo").toString();
responseMap.put(serialNo,response);
}
for(Request request : requests){
Map<String,Object> result = responseMap.get(request.serialNo);
request.future.complete(result);
}
},0,10,TimeUnit.MILLISECONDS);
}