JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

Java异步记录日志-2022新项目

wys521 2024-11-27 12:14:00 精选教程 16 ℃ 0 评论

一、业务场景

web 项目开发中,经常会有的一个操作是记录请求日志,比如记录请求的 IP 地址,记录请求的路径,记录请求的参数等等。

每个系统都会根据自己的需要来记录一些请求相关的日志。一般会将记录的日志信息保存到数据库中,以便于查看,如出现异常

高频率的访问请求,或者是遇到其他一些问题都可以查看记录的日志来进行排查问题。如果系统的请求比较少的话,直接记录日志

则没什么问题,可是如果请求量比较大的时候,如何来优化日志记录的操作呢?

二、需求分析

本篇文章所说的这种方式是使用异步的方式来记录日志。 Java 代码一般都是同步执行,所谓同步执行,简单理解

就是从上往下执行, 必须要等待上一行代码执行完之后,才会执行下一行代码。了解前端的同学应该对异步操作并不

陌生,页面中的很多 ajaxx 请求大多都是 异步执行的,并不一定要等前面一行的代码执行完,后面一行的代码也可以执

行。可是在 Java 中如何来进行异步操作呢?

三、解决方案

从当前项目中 学习到的方式如下:

大致的思路是,在 web 项目中使用拦截器来拦截需要记录日志的请求,在这个拦截器的拦截方法中,获取一个记录日志的任务对象,

对象是多实例的。然后使用 这个对象设置一些指定的值,比如请求路径,请求 IP ,请求求时间信息等等。将这些值设置好之后,在使用

一个工具类来调用方法,传入的参数 为这个任务处理类。之后就可以使用异步线程的方式来记录请求的日志数据。自己模仿项目中的方

式写的代码如下 :

拦截器中的代码 :

@Slf4j

public classLogRecordInterceptor **implements** HandlerInterceptor{

@Autowired

privateLogRecordRunnableTask **logRecordRunnableTask** ;

@Override

public booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) **throws** Exception {

try{

String requestURL = request.getRequestURL().toString();

logRecordRunnableTask.setUrl(requestURL);

logRecordRunnableTask.setRequestTime(CommonUtil. *getCurrentDateTime* ());

RecordLogRunnableUtils. *submit* ( **logRecordRunnableTask** );

} **catch** (Exception ex) {

*log* .error( **"日志记录异常--->{}"** , ex);

}

return true;

}

}

注册拦截器bean对象的代码 :

@Configuration

public classWebMvcConfig **extends** WebMvcConfigurerAdapter {

*/****      *  Function:  addInterceptors**      *  Author :  kaye0110,**     *  Version : 1.0**      *  Description : 注册拦截器                            **      *  Param and Description :  **      *   ****@param* *****registry*****/* @Override

public voidaddInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(logRecordInterceptor()).addPathPatterns( **"/**"** );

super.addInterceptors(registry);

}

@Bean

publicLogRecordInterceptor logRecordInterceptor(){

return  newLogRecordInterceptor();

}

}

日志任务处理类的代码

@Data

@Component

@Scope( **"prototype"** )

public classLogRecordRunnableTask **implements** Runnable{

@Autowired

privateLogRecordService **logRecordService** ;

*/***      * 请求地址**      */* **private** String **url** ;

*/***      * 请求时间**      */* **private** String **requestTime** ;

@Override

public voidrun() {

logRecordService.createLogRecord( **url** , **requestTime** );

}

}

注意:这个类是多实例的,类中实现 Runnable 接口,重写 Run 方法,就在这个方法中执行记录日志的操作。

Service 接口实现类的代码 .

@Slf4j

@Service

public classLogRecordServiceImpl **implements** LogRecordService {

@Override

public voidcreateLogRecord(String url, String recordTime) {

*log* .info( **"url-->{}, recordTime--->{}"** , url, recordTime);

}

}

日志记录工具类的代码

@Slf4j

public classRecordLogRunnableUtils {

privateRecordLogRunnableUtils(){}

private staticExecutorService *executor* = Executors. *newFixedThreadPool* (20);

*/* @Description: 执行日志记录操作**       * @author: yilang**       * @date: 2022/7/27 13:03**       * @param: runnable**       * @return: void**       */* **public static void** submit(Runnable runnable) {

try{

*executor* .submit(runnable);

} **catch** (Exception ex) {

*log* .error( **"执行日志操作异常:{}"** , ex);

}

}

}

简单测试了一下,使用 postman 一次性发 30 个请求 .

测试结果如下结果符合预期,程序正常执行,后台记录日志的时候是使用多线程的方式来进行处理的。

以后有需要的同学完全可以采用这种方式,来优化日志记录的操作,当访问量越来越大时,这种方式的优点也会提现得更加明显。

以前也有同事使用过其他方式来优化日志记录,首先将请求的日志信息保存在的 redis 中,然后另外跑一个定时任务定时去取

这些日志信息, 如果日志信息大于 100 条则将其存储在数据库中,并且删除已保存的 数据。这样在一定程度上也可以提高日志

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表