高并发场景下的请求合并

一.

在项目中,我们经常用到如下方式进行接口调用:

有多少请求访问,就会调用多少次第三方接口或数据库,这样的情况在高并发场景下很容易出现线程被打满,返回结果慢。

为了优化这个接口,后台可以将相同的请求进行合并,然后调用批量的查询接口。

  

请求合并:

下面上代码:

已查询数据库举例

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();



        }

    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值