线程池+队列实现日志定时批量提交日志

来源:互联网 发布:淘宝售后服务怎么写 编辑:程序博客网 时间:2024/06/05 17:51

最近有个需求需要记录用户操作记录,实现起来无非是用aop直接记录日志。用自定义注解,通过属性文件建立注解和具体操作的映射关系,然后用aop切入持有该注解的接口,记录操作信息。
这种在并发不高的系统上是可行的,一旦并发量略高,aop里的插入DB操作势必会影响接口响应时间,对性能影响还是有一些的。因此将其改为系统定时批量插入日志。下面直接贴代码。具体实现全写在注释里了。

//@Componentpublic class TaskThreadPools {    @Autowired    private ManagerService managerService;    @Autowired    private OperationLogService operationLogService;    private static final org.apache.commons.logging.Log log = LogFactory.getLog(TaskThreadPools.class);    //线程池对队列的操作可能并发,需要volatile保证队列内存可见性    private static volatile Queue<QueueDealStructure> dataQueue;    private volatile List<OperationLog> logs = Collections.synchronizedList(new ArrayList<>());    public static Queue<QueueDealStructure> getQueueInstance() {        if (dataQueue == null) {            //LinkedList实现了Queue接口,可以用LinkedList做一个队列,这里使用阻塞队列BlockingQueue            dataQueue = new LinkedBlockingQueue<>();        }        return dataQueue;    }    public void commitLogPool() {        /**        *@Author hfismyangel@163.com        *@Description:定时任务线程池自动提交日志        *@Date: 20:01 2017/10/13           * @param        */        if (getQueueInstance().peek() != null) {            log.info("===================poll is not null,make Executor>>");            int size;            //初始化固定容量为队列长度的Executor            ExecutorService threadPoolExecutor = Executors.newFixedThreadPool((size = getQueueInstance().size()));            for (int i = 0; i < size; i++) {                threadPoolExecutor.submit(new Runnable() {                    @Override                    public void run() {                        QueueDealStructure poll;                        if ((poll = getQueueInstance().poll()) != null) {                            try {                                String keyIdentity = poll.getKeyIdentity();                                String property = poll.getProperty();                                log.info("===================thread start and Thread id>>" + Thread.currentThread().getId());                                Long adminId = Long.valueOf(keyIdentity);                                Manager admin = managerService.getObjectById(adminId);                                //创建日志对象                                OperationLog operationLog = new OperationLog();                                operationLog.setAdmin(admin.getName());                                operationLog.setOperation(property);                                operationLog.setCreateBy(adminId);                                operationLog.setUpdateBy(adminId);                                logs.add(operationLog);                            } catch (Exception e) {                                e.printStackTrace();                            }                        }                    }                });            }            //及时关闭,否则可能引起内存泄露            threadPoolExecutor.shutdown();            if (logs.size() != 0) {                try {                    //批量插入                    operationLogService.insertList(logs);                    log.info("==================insert database finish>>");                    logs.clear();                } catch (Exception e) {                    e.printStackTrace();                }            }        }    }    @Scheduled(cron = "0 0 0/1 * * ?")    public void timer() {        //spring timer定时提交任务        commitLogPool();    }}
原创粉丝点击