一.
在项目中,我们经常用到如下方式进行接口调用:
有多少请求访问,就会调用多少次第三方接口或数据库,这样的情况在高并发场景下很容易出现线程被打满,返回结果慢。
为了优化这个接口,后台可以将相同的请求进行合并,然后调用批量的查询接口。
请求合并:
下面上代码:
已查询数据库举例
1.创建请求类:
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Request<T> {
private String code;
private String serialNo;
private CompletableFuture<T> future;
}
2.具体业务处理类:
@Component
public class CompletableFutureTest {
LinkedBlockingQueue<Request> queue = new LinkedBlockingQueue();
@Autowired
private RubbishService rubbishService;
@PostConstruct
public void init(){
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try{
if(queue.size() == 0){
return;
}
int size = queue.size();
List<Request> requests = new ArrayList<>(size);
for(int i=0;i<size;i++){
requests.add(queue.poll());
}
List<String> codes = new ArrayList<>();
for (Request request : requests) {
codes.add(request.getCode());
}
HashMap<String, Rubbish> responseMap = new HashMap<>();
List<Rubbish> rubbishes = rubbishService.getRubbishByRubbishIds(codes);
for (Rubbish rubbish : rubbishes) {
responseMap.put(rubbish.getRubbishId(),rubbish);
}
//将结果响应给每一个单独的用户请求。
for (Request request : requests) {
//根据请求中携带的能表示唯一参数,去批量查询的结果中找响应。
Rubbish result = responseMap.get(request.getCode());
//将结果返回到对应的请求线程。2个线程通信,异步编程赋值。
//complete(),源码注释翻译:如果尚未完成,则将由方法和相关方法返回的值设置为给定值
request.getFuture().complete(result);
}
}catch (Exception e){
e.printStackTrace();
}
}
},0,100, TimeUnit.MILLISECONDS);//每100mm从队列中取一次数据
}
public void future(String id)throws Exception {
List<String> list = new ArrayList<>();
list.add("A19070119121163727");
list.add("A19070119121163727");
list.add("A19070119121163727");
for(int i = 0;i<list.size();i++){
String s = list.get(i);
new Thread(){
@Override
public void run() {
try{
Request request = new Request();
request.setSerialNo(UUID.randomUUID().toString());
request.setCode(s);
CompletableFuture<Rubbish> future = new CompletableFuture<Rubbish>();
request.setFuture(future);
queue.put(request);
Rubbish stringObjectMap = future.get();
System.out.println(JSONObject.toJSONString(stringObjectMap));
}catch (Exception e){
e.printStackTrace();
}
}
}.start();
}
}
}