Springboot项目一次粗糙优化接口的记录

优化问题:

发现项目中一个页面模块响应时间很慢,等关注的时候才知道是报错,通过分析得出,并不是因为逻辑错误,而是因为超时,从而引起近两天的冥思苦想(ps:感觉好无助的。。。。)

 


分析问题:

经过对接口的分析发现,原来没事出现这种问题的原因是因为数据涉及的不多,慢慢积累之后就出现了这样的问题;因为功能的需要,要把固定省份下的十几个地市的数据展示出来,那么就是要list循环获取需要的数据,只是这样还没事,最后还要分别获取每个地市下的其他相关数据的list,然后根据获取的list里的数据进行其他的操作,或者获取list,这样一系列的操作之下,就显示很慢很慢,由于项目和自身接触的限制,对于解决问题还是费了很大的精力


解决方案:

一,对于类似请求超时,大多数是要设置什么超时时间,但是貌似不适用我这个项目(不知道是不是有其他限制,没起作用),这里就不举例了

二,用异步调用;找了很多方法,通过结合自身项目的实践得出一个比较粗糙的方案(时间还是比较长,但是可以请求到不报错),虽然不是最优方案,但是能解决当前的问题。

1.先把获取的十几个地级市集合分割成若干集合,附上找到使用的方法:

/**
     * 将一组数据平均分成n组
     *
     * @param source 要分组的数据源
     * @param n      平均分成n组
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> averageAssign(List<T> source, int n) {
        List<List<T>> result = new ArrayList<List<T>>();
        //(先计算出余数)
        int remainder = source.size() % n;
        //然后是商
        int number = source.size() / n;
        //偏移量
        int offset = 0;
        for (int i = 0; i < n; i++) {
            List<T> value = null;
            if (remainder > 0) {
                value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
                remainder--;
                offset++;
            } else {
                value = source.subList(i * number + offset, (i + 1) * number + offset);
            }
            result.add(value);
        }
        return result;
    }

以上是把list分成平均的n组集合,方面后边的执行方式。

2.这里需要设置线程池的一些配置(搜刮来的):

@Configuration
public class ExecutorConfig {


    /**
     * 线程池
     *
     * @return
     */
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(15);
        executor.setQueueCapacity(25);
        executor.setKeepAliveSeconds(200);
        executor.setThreadNamePrefix("async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务都完成再继续销毁其他的Bean
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
        executor.setAwaitTerminationSeconds(60);
        executor.initialize();
        return executor;
    }


}

然后,定义多个异步执行方法,类似下面这样的方式:

    @Override
    @Async("asyncExecutor")
    public Future<VO>> getShowA(){

        执行逻辑
    }

    @Override
    @Async("asyncExecutor")
    public Future<VO>> getShowB(){

        执行逻辑
    }

调用异步A和B方法,分别获取A和B的数据,执行时间大大缩短;还有一些for循环换成Java8方式循环,多少也会节省一点

粗糙的东西慢慢细化吧,目前刚刚解决问题,等待进一步优化。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值