Cloud-Platform 学习——Part5 日志保存系统
1.ace-gate
启动类
启动日志记录线程,项目一启动就开始运行
public class GatewayServerBootstrap { public static void main(String[] args) { DBLog.getInstance().start();//启动日志线程 SpringApplication.run(GatewayServerBootstrap.class, args); } }
生成日志信息
1.阻塞队列添加数据
//注入logService 的bean @Autowired private LogService logService; // DBLog.getInstance().setLogService(logService).offerQueue(logInfo); //logInfo为日志信息类,此处省略
2.获取阻塞队列数据并调用保存日志服务
@Slf4j public class DBLog extends Thread { private static DBLog dblog = null;//日志类 private static BlockingQueue<LogInfo> logInfoQueue = new LinkedBlockingQueue<LogInfo>(1024);//阻塞队列 private LogService logService; public LogService getLogService() { return logService; } public DBLog setLogService(LogService logService) { if(this.logService==null) { this.logService = logService; } return this; } //单例模式 public static synchronized DBLog getInstance() { if (dblog == null) { dblog = new DBLog(); } return dblog; } private DBLog() { super("CLogOracleWriterThread"); } public void offerQueue(LogInfo logInfo) { try { //待保存的日志信息类放入阻塞队列 logInfoQueue.offer(logInfo); } catch (Exception e) { log.error("日志写入失败", e); } } @Override public void run() { List<LogInfo> bufferedLogList = new ArrayList<LogInfo>(); // 缓冲队列 while (true) { try { //take()会获取队列头数据,并移除,如果队列为空,会一直阻塞等待,直到可获取 bufferedLogList.add(logInfoQueue.take()); logInfoQueue.drainTo(bufferedLogList);//把阻塞队列所有数据放入缓冲队列 if (bufferedLogList != null && bufferedLogList.size() > 0) { //挨个保存日志 for(LogInfo log:bufferedLogList){ logService.saveLog(log); } } } catch (Exception e) { e.printStackTrace(); // 防止缓冲队列填充数据出现异常时不断刷屏 try { Thread.sleep(1000); } catch (Exception eee) { } } finally { if (bufferedLogList != null && bufferedLogList.size() > 0) { try { bufferedLogList.clear(); } catch (Exception e) { } } } } } }
LinkedBlockingQueue使用优点:
- 线程安全:LinkedBlockingQueue实现了同步和锁定机制,保证了多个线程同时访问时的线程安全性。
- 可伸缩性:LinkedBlockingQueue是基于链表实现的,可以动态地增加或减少节点,从而调整队列的大小。
- 阻塞性:当队列为空时,从队列中获取元素的操作会阻塞,直到队列中有新的元素插入;当队列已满时,向队列中插入元素的操作会阻塞,直到队列中有元素被移除。
保存日志服务发送保存请求
LogService
定义日志保存接口
public interface LogService { void saveLog(LogInfo info); }
LogServiceImpl
具体实现日志保存接口
@Component @Slf4j public class LogServiceImpl implements LogService { @Autowired private WebClient.Builder webClientBuilder; @Override public void saveLog(LogInfo info) { //WebClient根据异步发送http日志保存请求 Mono<Void> mono = webClientBuilder.build(). post().uri("http://ace-admin/api/log/save") .body(BodyInserters.fromValue(info)) .retrieve() .bodyToMono(Void.class); // 输出结果 log.debug(String.valueOf(mono.block())); } }
2.ace-admin
接收日志请求
LogRest
定义接口接收日志请求,并通过
@RequestMapping("/api") @RestController @Slf4j public class LogRest { @Autowired private GateLogBiz gateLogBiz; //接收WebClient根据发送的请求 @RequestMapping(value = "/log/save", method = RequestMethod.POST) public @ResponseBody void saveLog(@RequestBody LogInfo info) { GateLog log = new GateLog(); BeanUtils.copyProperties(info, log); log.setCrtTime(new Date(info.getCrtTime())); gateLogBiz.insertSelective(log); } }
GateLogBiz
插入日志信息到数据库
@Service @Transactional(rollbackFor = Exception.class) public class GateLogBiz extends BaseBiz<GateLogMapper,GateLog> { @Override public void insert(GateLog entity) { mapper.insert(entity); } @Override public void insertSelective(GateLog entity) { mapper.insertSelective(entity); } }
标签:
学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异