Cloud-Platform 学习——Part5 日志保存系统

发布时间:2023年12月30日

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);
    }
}
文章来源:https://blog.csdn.net/2301_78055266/article/details/135280544
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。