• 性能优化,定时批量入库支持类设计


    并发量很高,在不引入中间件的情况下,自己写队列进行存储数据,然后定时批量获取,入库。

    直接上代码,测试支持类:

    import org.apache.commons.collections.CollectionUtils;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.stream.Collectors;
    
    /**
     * <P>
     * 描述:批量插入支持,用於批量插入加到隊列,批量獲取
     * </p>
     *
     * @author lishang Created on 2020/10/22 15:44
     * @version 1.0
     */
    public class BatchSupport<T> {
    
        /**
         * 公用阻塞队列
         */
        private LinkedBlockingQueue<T> queue = new LinkedBlockingQueue();
    
    
        /**
         * 将集合中的所有数据刷出
         * @return
         */
        public  List<T>  flush() {
            List<T> result=new ArrayList<>();
            queue.drainTo(result);
            result=result.stream().filter(dto -> dto != null).collect(Collectors.toList());
            return result;
        }
    
        /**
         * 批量插入List到缓冲对象中
         * @param dtoList
         */
        public void addList(List<T> dtoList) {
            if (CollectionUtils.isEmpty(dtoList)) {
                return;
            }
            queue.addAll(dtoList);
        }
    
    
    
    
    }

    插入支持类:

    import cn.hsa.ims.common.enums.TableName;
    import cn.hsa.ims.common.rdsutils.BatchOperation;
    import com.alibaba.fastjson.JSONArray;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    
    /**
     * <P>
     * 描述:批量插入支持类
     * </p>
     *
     * @author xxx Created on 2020/10/23 12:41
     * @version 1.0
     */
    @Component
    public class BatchInsertSupport {
        private static final Logger LOGGER = LoggerFactory.getLogger(BatchInsertSupport.class);
        @Autowired
        @Qualifier("batchOption-adb")
        private BatchOperation batchOperationDrds;
    
        /**
         * 批量插入方法
         * @param tableName
         * @param list
         */
        public void batchInsert(TableName tableName, List<?> list){
            if (list==null){
                LOGGER.info("准备插入{},没有获取到数据,批量方法结束",tableName);
                return;
            }
            try {
                long start=System.currentTimeMillis();
                batchOperationDrds.batchInsert(list, tableName.name(), 1000);
                long end=System.currentTimeMillis();
                LOGGER.info("结束批量插入{}表记录条数:{},耗时:{}",tableName,list.size(),(end-start));
            } catch (Exception e) {
                e.printStackTrace();
                LOGGER.error("批量插入{}表异常,异常信息:{}",tableName, e.getMessage());
                LOGGER.error("异常数据为:{},共{}条", JSONArray.toJSONString(list),list.size());
            }
        }
    }

    业务表flush方法和batchInsert方法:

    /**
         * 批量插入
         *
         * @param bffactWarnCallDTOS
         */
        @Override
        public void batchInsert(List<BffactWarnCallDDTO> bffactWarnCallDTOS) {
            batchSupport.addList(bffactWarnCallDTOS);
        }
    
        /**
         * 将队列中的刷到数据库中
         */
        @Override
        public void flush() {
            List<BffactWarnCallDDTO>  list = batchSupport.flush();
            batchInsertSupport.batchInsert(TableName.BFFACT_WARN_CALL_D,list);
        }

    定时任务处理:

    Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    LOGGER.info("定时入库TimeTask.......Start");
                    xxxBO.flush();
               
                    LOGGER.info("定时入库TimeTask.......End");
                }
            }, 1, 1000 * 60 * minutes);

    整个处理流程大致如此,解决了批量入库耗时问题。

  • 相关阅读:
    Linux Hung Task分析
    Linux内存都去哪了:(1)分析memblock在启动过程中对内存的影响
    《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll
    Linux内核和用户空间通信之netlink
    Linux soft lockup分析
    一款DMA性能优化记录:异步传输和指定实时信号做async IO
    Linux下时钟框架实践---一款芯片的时钟树配置
    使用Kernel NetEm和tc模拟复杂网络环境
    使用Flame Graph进行系统性能分析
    sigsuspend()阻塞:异步信号SIGIO为什么会被截胡?
  • 原文地址:https://www.cnblogs.com/sloveling/p/batch_insert.html
Copyright © 2020-2023  润新知