简单日志实现
程序员文章站
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);
}
}
}
上一篇: 判断对象是否存在