一、基于AOP(切面)或者拦截器 传统的实现方案
优点
:实现思路简单;
缺点
:增加数据库的负担,强依赖前端的传参,不方便拓展,不支持批量操作,不支持多表关联;
优化缺点
: 但是这个缺点可以换成Elasticsearch进行存储与查询
实现方式
:AOP切面实现操作日志
AOP实现返回值与请求参数
:
//获取请求参数
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
/**
* 方法成功return之后的advice
* @param point
* @param returning
*/
@AfterReturning(value = "pointcut()",returning = "returning")
public void after(JoinPoint point, Object returning) {
//获取response值
JSON.toJSONString(returning);
}
/**
* 报错之后的advice
* @param throwing
*/
@AfterThrowing(value = "pointcut()",throwing = "throwing")
public void error(Throwable throwing) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
//获取报错信息
throwing.printStackTrace(new PrintStream(byteArrayOutputStream));
byteArrayOutputStream.toString()
} catch (IOException e) {
log.error("存入数据异常:{}",e.getMessage());
}
}
二、基于数据库Binlog
优点
:解除了数据新旧变化的耦合,支持批量操作,方便多表关联拓展,不依赖开发语言;
缺点
:数据库表设计需要统一的约定; 如果分库分表;或者集群化数据库;可能需要特殊进行处理。
框架
:canal,但区别在于canal是模拟mysqlslave端,主动从master端拉取日志数据。而mysql-binlog-connector只是一个解析库,它有两种模式:BinaryLogFileReader日志读取模式,和BinaryLogClient客户端访问模式。但似乎,BinaryLogFileReader日志读取模式更适合于可中断可指定position读取的的模式。
实现方式
:
<!-- https://mvnrepository.com/artifact/com.github.shyiko/mysql-binlog-connector-java -->
<dependency>
<groupId>com.github.shyiko</groupId>
<artifactId>mysql-binlog-connector-java</artifactId>
<version>0.20.1</version>
</dependency>
package com.xxxx.faceadd;
import com.github.shyiko.mysql.binlog.BinaryLogClient;
import com.github.shyiko.mysql.binlog.BinaryLogFileReader;
import com.github.shyiko.mysql.binlog.event.Event;
import com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer;
import java.io.File;
import java.io.IOException;
public class MysqlBlong {
public static void main(String[] args) throws IOException {
String filePath="D:\\DATA\\mysql-bin.000987";
File binlogFile = new File(filePath);
EventDeserializer eventDeserializer = new EventDeserializer();
eventDeserializer.setCompatibilityMode(
EventDeserializer.CompatibilityMode.DATE_AND_TIME_AS_LONG,
EventDeserializer.CompatibilityMode.CHAR_AND_BINARY_AS_BYTE_ARRAY
);
BinaryLogFileReader reader = new BinaryLogFileReader(binlogFile, eventDeserializer);
try {
for (Event event; (event = reader.readEvent()) != null; ) {
//TODO 编写业务逻辑
}
} finally {
reader.close();
}
//监听日志变化
BinaryLogClient client = new BinaryLogClient("hostname", 3306, "username", "password");
client.registerEventListener(event -> {
//TODO 编写业务逻辑
});
}
}