我应该如何优化接口呢?(CompletableFuture)

背景:前些天在业务不怎么繁忙的时候,我主动用kibana、grafana 创建了一份属于我负责服务的接口性能图,通过性能图就能轻松看出每个接口的响应时间。那么问题来了:我应该如何优化慢查询呢? 我应该通过什么工具来看出我需要优化哪些点呢? 我应该如何实现优化呢?用到的技术点有哪些呢?

grafana 可视化表:

 kibana 可视化表:

可以依据自己想看的报表建立相关的可视化,然后通过可视化来排查哪些接口存在性能问题、又有哪些接口存在错误问题等。当找到待优化的接口之后,紧接着就是要明确应该如何优化接口,也需要明确接口中那一块依赖服务请求时间长?这个时候就可以依托与SkyWalking来分析接口内部的优化点。(SkyWalking是一个开源的框架,后面更新搭建教程)。

SkyWalking 面板:

 通过SkyWalking 面板就能看出来接口内部每个服务调用方接口、数据库操作等,每个接口的具体访问时间,数据库连接时间等都可以一目了然。 从而调查代码,找到相关的调用处,进行修改。

 假设从上面SkyWalking 中抽象出的一个接口如下图所示,X轴表示方法执行的时间,Y轴表示执行的顺序(从上往下看),也就是先执行 getHasNoOrders  () (获取订单结果) checkData() (校验数据项) saveCheckResult() (保存数据)。可见上面三个函数之间执行方式串行执行,如果能够让他们之间的操作并行化,那么系统的性能就可以得到进一步提升了。

 那么应该如何使用异步任务完成呢? 假设:getHasNoOrders  () (获取订单结果) checkData() (校验数据项)这两个函数可以并行执行,在执行完之后 在执行  saveCheckResult() (保存数据),这样就可以将前面的  串行改并行了,整体响应时间就会减少,从而性能就能提高。

 如何实现上述的 串行改并行呢?

异步任务:CompletableFuture

涉及到 串行关系,并行关系,聚合关系的,一般用的最多的就是CompletableFuture,CompletableFuture 是Java 8 新增加的Api,该类实现,Future和CompletionStage两个接口,提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性。它继承了FutureTask的同步任务的特点,同时新增了异步调用的特点,其中异步的方法名称都带有Async。

创建CompletableFuture对象

方式一:使用默认线程池(默认采用的是ForkJoinPoin线程池,前提是cpu是多核的,也就是Runtime.getRuntime().availableProcessors() - 1,例如cpu是12核心的,那么就是返回11)

/**
 * 创建一个不带返回值得任务。
 */
CompletableFuture<Void> f1 = CompletableFuture.runAsync(new Runnable() {
     @Override
     public void run() {
      //业务逻辑          
     }
 });

方式二:使用自定义线程池(建议使用,不同的业务设定不同线程池,这样可以使性能达到最高水平)

//创建线程池
ExecutorService    executor =    Executors.newFixedThreadPool(10); 
        
//创建一个不带返回值得任务。
CompletableFuture<Void> f1 = CompletableFuture.runAsync(new Runnable() {
    @Override
    public void run() {

    }
},executor);

通过下面demo就能得到串行与并行之间的执行对比了:

public class ThreadDemo {

    public static void main(String[] args) {

        long start = System.currentTimeMillis();

        CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("第一个异步任务");
        });


        CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("第二个异步任务");
        });


        CompletableFuture<Void> f3 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("第三个异步任务");
        });

        //全部完成,执行该函数下面的方法
        CompletableFuture.allOf(f1, f2, f3).join();

        long end = System.currentTimeMillis();

        //大致预估时间 2 + 1 + 4 = 7
        System.out.println("串行行执行最优时间:7s");
        System.out.println("并行执行时间:" + (end - start) / 1000 + "s");
    }
}

运行结果: 

相关API

情景一:异步组合两任务都完成,在执行任务三。

情景二:异步组合两任务只要有一个完成,就执行任务三。

情景三:多任务组合完成  allOf

情景四:多任务只要有一个完成了。 anyOf

推荐详细API使用博客:

CompletableFuture中方法的各种(多任务并发场景)使用案例----详解_诗水人间-CSDN博客

最后:欢迎大家【私信】和【评论】,如果可以的话,还请关注我O。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值