调用第三方接口优化点

调用第三方接口优化点

import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.*;
/*
https://www.bilibili.com/video/BV1YV41147wb?p=7
b栈上面学习到的。
链接:https://www.bilibili.com/video/BV1YV41147wb?p=7
当我们去请求第三方的接口时。我们每次请求只需要传入一个id拿到对应的数据。
但如果我们请求量很大。可能将第三方搞崩溃。
如果第三方有提供批量接口。 我们可以将请求的id先存在本地。 然后10ms,批量请求一次。
结果放入CompletableFuture里面。 然后通过其get()方法,complete() 唤醒get()。等待结果的返回。

注意点:
1. 批量接口有返回一个全局的id。 这样可以对应的单id的请求。
2.如果没有返回某一个id的值。一直ConcurrentLinkedQueue.get(), 感觉最好加一个过期时间。


 */

@Service
public class NextService {

    ConcurrentLinkedQueue<Request> queue = new ConcurrentLinkedQueue<>();
    class Request<T> {
        Integer id;
        String res;
        CompletableFuture<T> future;
    }

    public String get(Integer id) throws ExecutionException, InterruptedException {
        // 原: 每次调第三方,单个接口
        // return "第三方接口" + id;
        CompletableFuture<String> completableFuture = new CompletableFuture();
        Request<String> request = new Request();
        request.id = id;
        request.future = completableFuture;

        queue.add(request);
        return completableFuture.get();


    }
    @PostConstruct
    public void dealQueueTask(){
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);

        scheduledThreadPoolExecutor.scheduleWithFixedDelay(()->{
            if(queue.size() == 0){
                return;
            }
            // 批量拿出数据  拼装批量参数  批量请求


          /*
           放入结果
            Request poll = queue.poll();
            poll.future.complete("结果");*/
        }, 0, 10, TimeUnit.MILLISECONDS);
    }



}

hystrix 请求合并

依赖 springboot、maven、jdk版本有要求

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

启动类

      @EnableHystrix

请求合并配置

import app.cn.in.StringService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Future;
@Service
public class StringServiceImpl implements StringService {

    @Override
    @HystrixCollapser(batchMethod = "more",
            // 控制请求合并的作用域,默认是REQUEST,就是不会跨越多个请求会话的,只在当前用户请求中合并多次请求为         //批处理请求。这里改成GLOBAL,就是可以跨越request context,合并不同用户的请求为一次批处理请求。
            scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
            // 此属性设置创建批处理后触发其执行的毫秒数。
            collapserProperties = {@HystrixProperty(name ="timerDelayInMilliseconds",value = "100"),
                    // 此属性设置在触发批处理执行之前批处理中允许的最大请求数。
                    @HystrixProperty(name ="maxRequestsInBatch",value = "10")
                    // requestCache.enabled
                    //此属性指示是否为HystrixCollapser.execute()和HystrixCollapser.queue()调用启用请求高速缓存。
            })
    public Future<String> one(Integer id) {
        return null;
    }

    @Override
    @HystrixCommand
    public List<String> more(List<Integer> ids) {
        System.out.println(ids + "===================  ");
        if(CollectionUtils.isEmpty(ids)){
            return null;
        }
        List<String> res = new ArrayList<>(ids.size());
        ids.forEach(id->{
            res.add(id + UUID.randomUUID().toString());
        });
        return res;
    }
}

测试

@RequestMapping("/order")
@RestController
public class StrController {

    @Resource
    private StringService stringService;

    @GetMapping("/one")
    public String getOrders() throws ExecutionException, InterruptedException {
          this.stringService.one(1);
          this.stringService.one(2);
        Future<String> one = this.stringService.one(3);
        return one.get();

    }

效果是调用one方法 多个请求会合并去请求 more方法

在批量接口中对传入的数据排序 扰乱原来的顺序 则取用结果错误

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值