我正在尝试为我的 Spring Boot 应用程序实现一个审计层。到目前为止,我尝试了两种方法。
1) 创建了 1 个审计表,其中包含字段 user_name、table_name、column_name、old_value、new_value、uuid、event_type。
每当保存任何更改时,填充审计实体并保存它。
好处:
下降:
审计实体
2)使用javers进行审计
好处:
下降:
基准
处理具有 20 列(字段)的表(实体)中的 10 行,
使用方法 1 所用时间:24328 ms => 24 s
使用方法 2 所用时间:311292 ms => 311 s(近 12 次)
3) 不使用 Hibernate envers,因为创建的表数量会很高
有人可以提出一个更好的想法来进行上述优缺点的审计吗?我们的目标是,
每个表中有 10 到 25 列。
最佳答案
正如您所说,创建审计跟踪的常用方法是应用程序端库,如 envers 或 Javers。这些与持久性库 Hook ,它们会维护数据表中的特定列(“createdBy”、“lastUpdated”等),和/或将早期记录版本复制到某种形式的历史表中。
但是,这样做有一些缺点:
更改数据捕获分 3 步
通过数据库触发器捕获更改数据
另一种技术是数据库触发器。无论是从应用程序还是数据库本身发出的,它们都不会错过任何操作。批量结单也将被处理。
基于触发器的 CDC 的另一个优点是应用程序不知道您添加了整个审计层这一事实。
不利的一面是,在将触发器作为 OLTP 事务的一部分执行时,仍然存在延迟增加的问题。
触发器的替代解决方案(此处为 Postgresql):
使用逻辑复制将数据库更改(解码的 WAL 消息)从主服务器流式传输到使用 WAL 的从服务器,并启用审计触发器以捕获对从服务器上复制表的更改。
通过基于日志的方法捕获更改数据
使用
transaction log
时不存在上述问题作为审计和使用变更数据捕获的来源,以检索变更信息并将其发送到消息代理或基于持久日志,例如 Apache Kafka
.通常被认为是更改数据捕获的最佳方法,但不是最简单的设置解决方案。以异步方式运行,CDC 进程可以提取更改数据,而不会影响 OLTP 事务。
每当发生数据更改时,都会将条目添加到事务日志中。
在批量操作中更新或删除的每条记录都会有一个日志条目,因此可以为每个记录生成一个更改事件。
仍然是 CDC 如何访问元数据的问题,例如执行数据更改的应用程序用户、他们的 IP 地址、跟踪跨度 ID 或任何类型的相关 ID。
一种方法是有一个单独的表来存储此元数据。应用程序可以为每个事务在该表中存储一个带有特定
transactionId
的记录。 .数据更改事件将包含与更改相关联的 transactionID,因此数据更改事件和元数据记录可以相互关联。
关于java - 有效的审计方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61344112/