欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简单日志实现

程序员文章站 2022-06-03 09:44:51
...

单个jvm里单例的线程池即可,这种是spring配置文件形式,也可以直接代码创建静态全局共享的线程池

<!-- 埋点日志专用线程池 -->
<bean id="pointLogTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
		<!-- 核心线程数 -->
		<property name="corePoolSize" value="1" />
		<!-- 线程池维护线程的最大数量 -->
		<property name="maxPoolSize" value="15" />
		<!-- 允许的空闲时间, 默认60-->
		<property name="keepAliveSeconds" value="10" />
		<!-- 任务队列 -->
		<property name="queueCapacity" value="5000" />
		<!-- 线程超过空闲时间限制,均会退出直到线程数量为0 -->
		<property name="allowCoreThreadTimeOut" value="true" />
		<!-- 对拒绝task的处理策略 -->
		<property name="rejectedExecutionHandler">
			<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
		</property>
	</bean>

代码实现

@Controller
public class PointLogController {
	private final Logger log = LoggerFactory.getLogger(PointLogController.class);
	@Autowired
	private PointLogExecutor pointLogExecutor;
	@Autowired
    private PointLogService pointLogService;
	
	@RequestMapping(value = "/pointLog/addLog", method = RequestMethod.POST)
	public void addLogs(PointLogDTO pointLogDTO) {
		pointLogExecutor.addLog(pointLogDTO);
	}
}



*********************************
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Component
public class PointLogExecutor {
    
    private static Logger log = LoggerFactory.getLogger(PointLogExecutor.class);

    /** 默认队列大小 */
    private static final int DEFAULT_QUERY_SIZE = 40000;

    /**队列满足发送大小 */
    private static final int SEND_SIZE = 200;

    /** 缓存日志队列  */
    private static ArrayBlockingQueue<PointLogDTO> cacheLogQueue = new ArrayBlockingQueue<PointLogDTO>(
            DEFAULT_QUERY_SIZE, true);

    /** 线程池 */
    @Autowired
    private ThreadPoolTaskExecutor pointLogTaskExecutor; // 这就是配置文件里的哪个线程池  
    @Autowired
    private IPointLogRecordService pointLogRecordService; 
    
    public void addLog(PointLogDTO pointLogDTO) {
        cacheLogQueue.offer(pointLogDTO);
        
        if(!CollectionUtils.isEmpty(cacheLogQueue) && cacheLogQueue.size()>SEND_SIZE) {
        	log.info("队列长度 = {}", cacheLogQueue.size());
            List<PointLogDTO> logList = new ArrayList<PointLogDTO>();
            cacheLogQueue.drainTo(logList,SEND_SIZE);
            if(!CollectionUtils.isEmpty(logList)) {
                PointLogTask pointLogTask = new PointLogTask(pointLogRecordService,logList);
                pointLogTaskExecutor.execute(pointLogTask);
            }
        }
    }

}

*************************************************************************
public class PointLogTask implements Runnable {
    
    private static Logger logger = LoggerFactory.getLogger(PointLogTask.class);

    private IPointLogRecordService pointLogRecordService;
    private List<PointLogDTO> logList;
    
    public PointLogTask(IPointLogRecordService pointLogRecordService, List<PointLogDTO> logList) {
        this.pointLogRecordService = pointLogRecordService;
        this.logList = logList;
    }

    @Override
    public void run() {
        try {
            if (null != logList) {
                logger.info("埋点日志持久化{}条",logList.size());
                pointLogRecordService.addLog(logList);//存数据库操作
                logger.info("埋点日志成功{}条",logList.size());
            }
        } catch (Exception e) {
            logger.error("埋点日志异常", e);
        }
    }

}
相关标签: 日志 java