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使用优点:

  1. 线程安全:LinkedBlockingQueue实现了同步和锁定机制,保证了多个线程同时访问时的线程安全性。
  2. 可伸缩性:LinkedBlockingQueue是基于链表实现的,可以动态地增加或减少节点,从而调整队列的大小。
  3. 阻塞性:当队列为空时,从队列中获取元素的操作会阻塞,直到队列中有新的元素插入;当队列已满时,向队列中插入元素的操作会阻塞,直到队列中有元素被移除。

保存日志服务发送保存请求

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);
}
}
posted @   Acegzx  阅读(15)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示