首页 > 其他分享 >直播系统开发,接口异步调用一小步,耗时减少一大步

直播系统开发,接口异步调用一小步,耗时减少一大步

时间:2024-08-24 09:29:34浏览次数:12  
标签:异步 process System 耗时 一大步 beginTime InterfaceA InterfaceB

直播系统开发,接口异步调用一小步,耗时减少一大步

随着直播系统开发业务发展,底层数据量越来越大,业务逻辑也日趋复杂化,某些接口耗时也越来越长,这时候接口就需要进行性能优化了,当然性能优化主要跟业务相关涉及改造点可能各不相同,这里就来介绍异步调用多个接口减少响应时间。

适用条件

调用多个独立的接口,接口间无相互依赖关系
非耗时最大的接口占总耗时比重较大

优化前调用方式

优化前的代码按照顺序调用方式:

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DemoTest {

    public static void main(String[] args) throws Exception {
        long beginTime = System.currentTimeMillis();
        int processA = new InterfaceA().process();
        int processB = new InterfaceB().process();
        int result = processA + processB;
        log.info("执行结果:{} 耗时:{}", result, System.currentTimeMillis() - beginTime);
    }

    @Slf4j
    public final static class InterfaceA {
        Integer result = 1;

        public int process() {
            long beginTime = System.currentTimeMillis();
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                log.error("InterfaceA.process Exception");
            }
            log.info("执行接口InterfaceA.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
            return result;
        }
    }

    @Slf4j
    public final static class InterfaceB {
        Integer result = 1;

        public int process() {
            long beginTime = System.currentTimeMillis();
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                log.error("InterfaceB.process Exception");
            }
            log.info("执行接口InterfaceB.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
            return result;
        }
    }
}

 

执行结果:

21:40:17.603 [main] INFO DemoTest$InterfaceA - 执行接口InterfaceA.process 耗时:2002ms
21:40:19.612 [main] INFO DemoTest$InterfaceB - 执行接口InterfaceB.process 耗时:2001ms
21:40:19.613 [main] INFO DemoTest - 执行结果:2 耗时:4018

 

优化后调用方式

优化后的代码按照异步调用方式:

import cn.hutool.core.thread.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class DemoTest {
    private static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            5,
            5,
            60,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(1000),
            ThreadFactoryBuilder.create().setNamePrefix("线程名称-").build()
    );

    public static void main(String[] args) throws Exception {
        long beginTime = System.currentTimeMillis();

        List<Future<Integer>> futures = new ArrayList<>(2);
        List<Integer> results = new ArrayList<>(2);
        futures.add(pool.submit(() -> new InterfaceA().process()));
        futures.add(pool.submit(() -> new InterfaceB().process()));
        for (Future<Integer> item : futures) {
            results.add(item.get());
        }
        
        int result = results.get(0) + results.get(1);
        log.info("执行结果:{} 耗时:{}", result, System.currentTimeMillis() - beginTime);
    }

    @Slf4j
    public final static class InterfaceA {
        Integer result = 1;

        public int process() {
            long beginTime = System.currentTimeMillis();
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                log.error("InterfaceA.process Exception");
            }
            log.info("执行接口InterfaceA.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
            return result;
        }
    }

    @Slf4j
    public final static class InterfaceB {
        Integer result = 1;

        public int process() {
            long beginTime = System.currentTimeMillis();
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                log.error("InterfaceB.process Exception");
            }
            log.info("执行接口InterfaceB.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
            return result;
        }
    }
}

 

执行结果:

22:03:43.180 [线程名称-1] INFO DemoTest$InterfaceB - 执行接口InterfaceB.process 耗时:2004ms
22:03:43.180 [线程名称-0] INFO DemoTest$InterfaceA - 执行接口InterfaceA.process 耗时:2004ms
22:03:43.190 [main] INFO DemoTest - 执行结果:2 耗时:2020

 

此方式还可以结合CompletionService可实现异步任务和执行结果分离,大家可以自行搜索实践

强大的CompletableFuture JDK1.8

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Slf4j
public class DemoTest {

    public static void main(String[] args) throws Exception {
        long beginTime = System.currentTimeMillis();

        CompletableFuture<Integer> interfaceFuturesA = CompletableFuture.supplyAsync(() -> new InterfaceA().process());
        CompletableFuture<Integer> interfaceFuturesB = CompletableFuture.supplyAsync(() -> new InterfaceB().process());
        CompletableFuture<List<Integer>> future = CompletableFuture
                .allOf(interfaceFuturesA, interfaceFuturesB)
                .thenApply((none) -> {
                    List<Integer> dataList = new ArrayList<>(2);
                    try {
                        dataList.add(interfaceFuturesA.get());
                        dataList.add(interfaceFuturesB.get());
                    } catch (Exception e) {
                        log.error("执行异常");
                    }
                    return dataList;
                }).exceptionally(e -> Lists.newArrayList());

        int result = future.get().get(0) + future.get().get(1);
        log.info("执行结果:{} 耗时:{}", result, System.currentTimeMillis() - beginTime);
    }

    @Slf4j
    public final static class InterfaceA {
        Integer result = 1;

        public int process() {
            long beginTime = System.currentTimeMillis();
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                log.error("InterfaceA.process Exception");
            }
            log.info("执行接口InterfaceA.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
            return result;
        }
    }

    @Slf4j
    public final static class InterfaceB {
        Integer result = 1;

        public int process() {
            long beginTime = System.currentTimeMillis();
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                log.error("InterfaceB.process Exception");
            }
            log.info("执行接口InterfaceB.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
            return result;
        }
    }
}

 

执行结果:

22:31:44.822 [ForkJoinPool.commonPool-worker-5] INFO DemoTest$InterfaceB - 执行接口InterfaceB.process 耗时:2005ms
22:31:44.822 [ForkJoinPool.commonPool-worker-3] INFO DemoTest$InterfaceA - 执行接口InterfaceA.process 耗时:2002ms
22:31:44.831 [main] INFO DemoTest - 执行结果:2 耗时:2027

 

优化时注意点

在直播系统开发时,使用线程池防止内存溢出风险
执行结果容器可自行根据需要设置
接口粒度可根据实际业务情况组合和拆分

以上就是直播系统开发,接口异步调用一小步,耗时减少一大步, 更多内容欢迎关注之后的文章

 

标签:异步,process,System,耗时,一大步,beginTime,InterfaceA,InterfaceB
From: https://www.cnblogs.com/yunbaomengnan/p/18377366

相关文章

  • 直播电商源码,用异步加成打造更高性能
    直播电商源码,用异步加成打造更高性能单线程和异步js是单线程语言,同时只能做一件事浏览器和node已支持js启动进程,如WebWorkerjs和DOM渲染共用同一个线程,因为js可修改DOM结构遇到等待(网络请求,定时任务)不能卡住,所以需要异步同步会阻塞代码执行,异步不会阻塞代码......
  • lua协程实现异步编程模式
    异步编程模式只是一个代码结构,c#中的async/await的写法就是异步编程模式,这边就是通过协程来达到和async/await类似的效果。 异步编程模式写法1:资源分帧加载这边运行环境用的是:Unity+xLua lua脚本:Assets/Lua/Test9.lua.txtlocal_Time=CS.UnityEngine.Timelocalfunct......
  • Android开发 - Looper 类处理异步任务和消息解析
    什么是LooperLooper是一个非常重要的概念,它与线程、消息队列和处理异步任务密切相关。是Android中用于管理线程的消息循环的类。它与线程中的MessageQueue结合工作,用于处理异步任务和消息Looper的主要概念消息队列(MessageQueue)一个用于存放要处理的消息和任务的队......
  • 记一次vue数据异步刷新引发的bug
    问题背景在开发过程中,为了threejs对象在watch监听中能够被顺利取到,我加了一个信号量,在初始化对象后,通过threejs对象状态和表单状态来重新渲染画面。然而,我把threejs对象从null设置为正常的对象时,页面居然卡死了。在实际的代码中,用到对象的情况只有wacth里面监听到信号量为true时......
  • 消息队列作用(解耦、异步、削峰)
    原文:消息队列作用(解耦、异步、削峰)图详解一、消息队列简介简单来说,“消息队列”是在消息的传输过程中保存消息的容器。MQ全称为MessageQueue,消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信。消息传递指的是程......
  • 耗时一天,逆天数字华容道代码
    \(O(n^3)\)处理\(n\timesn\)数字华容道还原(可能无解)。具体实现看代码:solve.cpp#include<bits/stdc++.h>usingnamespacestd;#definefifirst#definesesecondconstintN=201;intn,l,r,L,R;booltype;vector<vector<int>>a,res;vector<p......
  • Python开发中,SQLAlchemy 的同步操作和异步操作封装,以及常规CRUD的处理。
    在我们使用Python来和数据库打交道中,SQLAlchemy是一个非常不错的ORM工具,通过它我们可以很好的实现多种数据库的统一模型接入,而且它提供了非常多的特性,通过结合不同的数据库驱动,我们可以实现同步或者异步的处理封装。1、SQLAlchemy介绍SQLAlchemy 是一个功能强大且灵活的Python......
  • 开源组件——异步日志方案 spdlog 的讲解
    一:日志的作用1、定义        日志(Log)是记录系统中发生的事件或操作的详细信息的文件或数据流。这些事件或操作可能包括程序执行、系统错误、用户活动、安全事件等日志(Log)是记录系统中发生的事件或操作的详细信息的文件或数据流。这些事件或操作可能包括程序执行、系......
  • 一次Kubernetes Pod内存异常导致的测试环境耗时异常问题排查过程
    概述在使用公司内部后台系统测试环境时发现一个请求加载慢的问题,简简单单的列表,查询MongoDB数据库,测试环境不过几百上千条数据而已,请求耗时居然高达5~6秒:作为对比,生产环境的请求响应截图如下:经过持续跟进,该后台系统所有列表页面测试环境普遍比生产环境慢,不管是MongoDB还是MyS......
  • HTN7862 4V~65V输入,2.8A异步降压变换器
    1、特点 2.8A降压,内置260mΩ功率管输入电压范围:4V~65V脉冲跳跃模式使得轻载下高效率·110uA静态电流最高2MHZ可编程开关频率峰值电流控制架构欠压保护、过流保护和过热关断保护无铅封装,ESOP82、应用·12V,24V,48V工业和电信电源轨系统·汽车系统分布式电源系统高......