通过Redis做消息队列,对其主项目的操作日志进行打印
生产消费模式
整体流程:
主项目的切面类中把要记录的日志信息从Redis消息队列的一头存入信息,而另一个日志记录的项目利用Spring定时任务从Redis队列的另一头取出日志信息并与数据库交互进行添加数据
这样做的好处可以减轻对数据库的压力,把数据存放在队列中(Redis)而不直接对数据库进行访问,这样一来日志的记录从多个访问,变成了一个。
下面是案例:
主项目的切面:
@After("myPointcut()")
public void after(JoinPoint jp) throws Throwable {
endtime=System.currentTimeMillis();
logBean.setEndtime(DateUtil.getDateTime());
logBean.setSumtime((endtime-starttime));
//通过Jedis对Redis的操作
exService.execute(new Thread(()->{
JedisUtil.lpush("logPool", JSON.toJSONString(logBean));
}));
}
日志项目的取出任务:
@Component
public class AsyncUtil {
@Resource
LogService logService;
@Async
@Scheduled(cron = "*/1 * * * * ?")
public void asyncOrder() throws Exception{
//判断Redis中是否存在key为logPool的值
if(RedisUtil.exists("logPool")){
//key为logPool的长度是否大于0
if(RedisUtil.Llen("logPool")>0){
/**
* 获取总长度对其-1,
* 因为下标从0开始,因为是队列,先入先出的规则,所以先存进去的被压在了底部
* 那么取出时应该每次取最底部的数据
* */
long leng=RedisUtil.Llen("logPool")-1;
//从队列取出数据
List<String> list= RedisUtil.lrange("logPool",leng,leng);
//将数据转为JSONObject
JSONObject str= (JSONObject) JSON.parse(list.get(0));
//将JSONObject转为日志实体类
LogBean logBean= (LogBean) JSONObject.toJavaObject(str,LogBean.class);
//向数据库进行添加日志
System.out.println(logService.add(logBean));
//删除队列的最右侧的一条数据,也就是最底部的,刚才取出的数据
RedisUtil.rpop("logPool");
}
}
}
}
这里需要注意的是,在SpringBoot中,无需配置Spring定时任务,但是需要在启动类中加上这两个注解来开启定时任务
@EnableAsync @EnableScheduling
总结:
以上就是日志项目和主项目的生产消费模式的记录写法
也是模块项目化的一个体现,日志模块改为单独的项目运行