查询接口优化(线程池异步调用)


前言

在项目中遇到一个接口响应时间比较慢,查看代码发现是有几个SQL查询加在一起比较慢,在SQL方面做了优化后发现还是比较慢。
此时发现业务中只需要这几个sql的结果进行拼接处理,因此考虑使用线程池异步运行多个sql的方式来提高接口响应时间。

以下为相关代码实现

一、配置线程池

application.yml

thread-pool:
  config:
    core-size: 8
    max-size: 16
    queue-capacity: 64
    keep-alive-seconds: 180

参数配置类

@Component
@ConfigurationProperties(prefix = "thread-pool.config")
@Data
public class TestThreadPoolConfig {

    private Integer coreSize;
    private Integer maxSize;
    private Integer queueCapacity;
    private Integer keepAliveSeconds;
}

线程池配置类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.RejectedExecutionHandler;
@Configuration
@EnableAsync
public class ThreadPoolConfig {

    @Autowired
    private TestThreadPoolConfig testThreadPoolConfig;

    /**
     * @return
     */
    @Bean(name = "testExecutor")
    public ThreadPoolTaskExecutor testThreadPoolExecutor() {
        return getAsyncTaskExecutor("test-Executor-", testThreadPoolConfig.getCoreSize(),
                testThreadPoolConfig.getMaxSize(), testThreadPoolConfig.getQueueCapacity(),
                testThreadPoolConfig.getKeepAliveSeconds(), null);
    }

    /**
     * 统一异步线程池
     *
     * @param threadNamePrefix
     * @param corePoolSize
     * @param maxPoolSize
     * @param queueCapacity
     * @param keepAliveSeconds
     * @param rejectedExecutionHandler 拒接策略 没有填null
     * @return
     */
    private ThreadPoolTaskExecutor getAsyncTaskExecutor(String threadNamePrefix, int corePoolSize, int maxPoolSize, int queueCapacity, int keepAliveSeconds, RejectedExecutionHandler rejectedExecutionHandler) {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(corePoolSize);
        taskExecutor.setMaxPoolSize(maxPoolSize);
        taskExecutor.setQueueCapacity(queueCapacity);
        taskExecutor.setThreadPriority(Thread.MAX_PRIORITY);//线程优先级
        taskExecutor.setDaemon(false);//是否为守护线程
        taskExecutor.setKeepAliveSeconds(keepAliveSeconds);
        taskExecutor.setThreadNamePrefix(threadNamePrefix);
        taskExecutor.setRejectedExecutionHandler(rejectedExecutionHandler);
        taskExecutor.initialize();//线程池初始化
        return taskExecutor;
    }
}

二、服务类

    @Autowired
    private ThreadPoolTaskExecutor testExecutor;
	@Override
    public List test() {
        CompletableFuture<List> future = CompletableFuture.supplyAsync(this::test01, testExecutor)
                .exceptionally(this::handleException);
        CompletableFuture<List> future2 = CompletableFuture.supplyAsync(this::test02, testExecutor)
                .exceptionally(this::handleException);

        CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future, future2);
        List vos = new ArrayList<>();
        combinedFuture.thenAccept(v -> {
            vos.addAll(future.join());
            vos.addAll(future2.join());
            System.out.println(vos);
        });

        combinedFuture.join();
        return vos;
    }

    private List handleException(Throwable t) {
        throw new RuntimeException("An exception occurred: " + t.getMessage(), t);
    }
    public List test01(){
        System.out.println("执行test01");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        List list = new ArrayList();
        list.add("111");
        list.add("222");
        System.out.println("执行test01结束");
        return list;
    }

    public List test02(){
        System.out.println("执行test02");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        List list = new ArrayList();
        list.add("333");
        list.add("444");
        System.out.println("执行test02结束");
        return list;
    }

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于使用 for 循环调用接口进行优化,有几个常见的方法可以考虑: 1. 批量处理:如果接口支持批量操作,可以将多个请求合并为一个批量请求,减少网络传输和接口调用的开销。这样可以减少循环次数,提高效率。 2. 并发请求:使用多线程、多进程或异步操作来并发发送多个请求,以减少等待时间。可以使用线程池或协程来管理并发操作,但要注意控制并发量,避免对接口服务器造成过大负荷。 3. 数据缓存:如果接口返回的数据可以缓存,可以考虑使用缓存来避免重复调用接口。可以使用内存缓存、数据库或其他缓存技术,根据数据的更新频率和实时性需求选择合适的缓存策略。 4. 分页查询:如果接口支持分页查询,可以通过设定合适的每页数据量和页码参数来获取特定范围的数据,避免一次性获取全部数据。这样可以减少接口调用次数和数据传输量。 5. 请求参数优化:根据接口的特性和需求,优化请求参数的设置,避免不必要的参数传递和数据处理。可以根据实际情况调整参数格式、过滤条件、排序方式等,减少数据传输和处理的开销。 需要根据具体情况选择合适的优化方法,并综合考虑接口性能、数据实时性、系统资源等因素进行权衡。同时,也要注意遵守接口的使用规范和限制,避免对接口服务端造成过大压力或违反服务协议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值