Java异步记录日志-2022新项目
一、业务场景
web项目开发中,经常会有的一个操作是记录请求日志,比如记录请求的IP地址,记录请求的路径,记录请求的参数等等。
每个系统都会根据自己的需要来记录一些请求相关的日志。一般会将记录的日志信息保存到数据库中,以便于查看,如出现异常
高频率的访问请求,或者是遇到其他一些问题都可以查看记录的日志来进行排查问题。如果系统的请求比较少的话,直接记录日志
则没什么问题,可是如果请求量比较大的时候,如何来优化日志记录的操作呢?
二、需求分析
本篇文章所说的这种方式是使用异步的方式来记录日志。Java代码一般都是同步执行,所谓同步执行,简单理解
就是从上往下执行,必须要等待上一行代码执行完之后,才会执行下一行代码。了解前端的同学应该对异步操作并不
陌生,页面中的很多ajaxx请求大多都是异步执行的,并不一定要等前面一行的代码执行完,后面一行的代码也可以执
行。可是在Java中如何来进行异步操作呢?
三、解决方案
从当前项目中学习到的方式如下:
大致的思路是,在web项目中使用拦截器来拦截需要记录日志的请求,在这个拦截器的拦截方法中,获取一个记录日志的任务对象,
对象是多实例的。然后使用这个对象设置一些指定的值,比如请求路径,请求IP,请求求时间信息等等。将这些值设置好之后,在使用
一个工具类来调用方法,传入的参数为这个任务处理类。之后就可以使用异步线程的方式来记录请求的日志数据。自己模仿项目中的方
式写的代码如下:
拦截器中的代码:
@Slf4j
public class LogRecordInterceptor implements HandlerInterceptor{
@Autowired
private LogRecordRunnableTask logRecordRunnableTask;
@Override
public boolean preHandle(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 class WebMvcConfig extends WebMvcConfigurerAdapter {
/**
* Function: addInterceptors
* Author : kaye0110,
* Version : 1.0
* Description : 注册拦截器
* Param and Description :
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(logRecordInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
@Bean
public LogRecordInterceptor logRecordInterceptor(){
return new LogRecordInterceptor();
}
}
日志任务处理类的代码
@Data
@Component
@Scope("prototype")
public class LogRecordRunnableTask implements Runnable{
@Autowired
private LogRecordService logRecordService;
/*
* 请求地址
*/
private String url;
/*
* 请求时间
*/
private String requestTime;
@Override
public void run() {
logRecordService.createLogRecord(url, requestTime);
}
}
注意:这个类是多实例的,类中实现Runnable接口,重写Run方法,就在这个方法中执行记录日志的操作。
Service接口实现类的代码.
@Slf4j
@Service
public class LogRecordServiceImpl implements LogRecordService {
@Override
public void createLogRecord(String url, String recordTime) {
log.info("url-->{}, recordTime--->{}", url, recordTime);
}
}
日志记录工具类的代码
@Slf4j
public class RecordLogRunnableUtils {
private RecordLogRunnableUtils(){}
private static ExecutorService 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条则将其存储在数据库中,并且删除已保存的数据。这样在一定程度上也可以提高日志
记录的效率,如果各位小伙伴还有更好的办法,欢迎留言讨论。
Java异步记录日志-2022新项目的更多相关文章
- mybatis-拦截器实际应用-替换表名-2022新项目
一.业务场景 考虑到新项目中部分与业务数据相关的表在后期数据量会比较大,架构师在最开始设计项目中与业务数据相关的表时,就已经考虑使用分表来 进行处理,给业务数据相关的每张表都添加统一批次的后缀,查询这 ...
- 项目开发中Maven的单向依赖-2022新项目
一.业务场景 工作多年,在真实的项目开发中经常会遇到将一个项目拆分成多个工程的情况,比如将一个真实的项目拆分成controller层,service层, dao层,common公共服务层等等.这样拆分 ...
- Java中list集合自定义排序-2022新项目
一.业务场景 为了加快首页数据查询的效率,因此将首页查询的数据大多数都放在了缓存中,包括各种list集合数据.对这些 从缓存中获取的数据做了一个兜底处理,如果从缓存中没有获取到数据,则直接从数据库中去 ...
- git实战-多分支开发-2022新项目
现在开发中大多数公司中都在使用Git这个代码版本管理工具,几乎可以说是已经成为标配,刚入职不久的这家新公司也不例外. 去公司没多久,开始搭建项目,然后创建开发分支,有多少个后端人员就创建多少个开发分支 ...
- 无法访问mybatis.dto.StudengInVO-使用maven编译报错-2022新项目
一.问题由来 最近一次拉代码后,合并代码然后进行编译时出现一个问题,使用maven在进行编译的时候报一个错,无法访问mybatis.dto.StudengInVO. 突然出现这个错误让自己感觉很奇怪, ...
- redis缓存恢复-2022新项目
一.业务场景 Web项目开发中,为了加快数据处理的的效率,大量的使用了各种缓存,缓存技术主要使用的是redis.导致出现的小小的 问题是对redis缓存形成了一个比较强的依赖,并且有的数据暂时是没有同 ...
- 程序包 applets.user.service.UserService 不存在-2022新项目
一.问题由来 接上一篇文章使用maven进行打包时报中文乱码错误,经过多次尝试后最终解决问题,显示出真正的错误信息如下: 程序包 applets.user.service.UserService 不存 ...
- postgresql使用group by进行数据去重-2022新项目
一.业务场景 数据去重是web开发中经常会遇到的方式之一,数据库操作中有一个关键字distinct主要就是用来做这件事,用来进行去重. 比如进行统计查询的时候,可以这样写 select count(d ...
- “快的打车”创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - V2EX
"快的打车"创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - ...
随机推荐
- c++ :STL
基础知识 容器 容器就是一些模板类的集合,不同之处就是容器中封装的是数据结构 1.序列容器 主要有vector向量容器.list列表容器.deque双端队列容器 元素在容器中是无序的 2.排序容器 包 ...
- 好客租房2-React概述
1.1什么是react React是一个用于构建用户界面的javascript库 用户界面:HTML页面 React主要用来HTML 或者沟通构建web应用 如果从MVC的角度来看 react仅仅是从 ...
- Mock 之搭建本地 MockJs
Mock 之搭建本地 MockJs 一.目的 模拟后端接口 二.发请求 1. install npm install axios 2. 配置 src/utils/request.js import a ...
- Redis(1)- Redis数据库的安装和配置
1.Redis安装 1.1.Linux环境安装Redis step-1:下载Redis 进入官网找到下载地址 https://redis.io/download wget https://github ...
- C++:制作火把
制作火把 时间限制 : 1.000 sec 内存限制 : 128 MB 题目描述: 小红最近在玩一个制作火把的游戏,一开始,小红手里有一根木棍,她希望能够通过这一根木棍通过交易换取制 ...
- 中国程序员容易发错音的单词「GitHub 热点速览 v.22.23」
中国程序员容易发错音的单词,像极了学生时代的纠错本,收录着偶尔会忘记的单词.不过,它似乎更新频率跟不上我们的进步速度,至少一半以上的单词读起来是没有压力的.同样没有压力的还有让应用程序动起来的 aut ...
- PostgreSQL Array 数组类型与 FreeSql 打出一套【组合拳】
前言 PostgreSQL 是世界公认的功能最强大的开源数据库,除了基础数据类型 int4/int8/varchar/numeric/timestamp 等数据类型,还支持 int4[]/int8[] ...
- Linux Cgroup v1(中文翻译)(1):Control Group
英文原文:https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cgroups.html 1 控制组 1.1 什么是控制组? 控制组 ...
- 【python】tile函数简单介绍
转:https://blog.csdn.net/april_newnew/article/details/44176059格式:tile(A,reps)* A:array_like* 输入的array ...
- CSS(九):background(背景属性)
通过CSS背景属性,可以给页面元素添加背景样式. 背景属性可以设置背景颜色.背景图片.背景平铺.背景图像固定等. background-color(背景颜色) background-color属性定义 ...