代码&优雅着&生活

导航

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

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

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

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);

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

posted on 2020-11-01 12:35  幸运的凌人  阅读(423)  评论(0编辑  收藏  举报