java - 有效的审计方式

标签 java performance spring-boot audit javers

我正在尝试为我的 Spring Boot 应用程序实现一个审计层。到目前为止,我尝试了两种方法。

1) 创建了 1 个审计表,其中包含字段 user_name、table_name、column_name、old_value、new_value、uuid、event_type。

每当保存任何更改时,填充审计实体并保存它。

好处:

  • 快速
  • 易于管理,因为只有 1 个审计表

  • 下降:
  • 有时它涉及太多从业务实体到
    审计实体
  • 必须从 db 获取旧值以填充审计实体
  • 手动创建审计实体
  • 检索可能会很痛苦


  • 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”等),和/或将早期记录版本复制到某种形式的历史表中。

    但是,这样做有一些缺点:

  • 作为 OLTP 事务的一部分在历史表中写入记录会增加事务中执行语句的数量 -> 可能会导致应用程序的响应时间变长
  • 支持批量更新和删除
  • 无法跟踪直接在数据库中进行的更改

  • 更改数据捕获分 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/

    相关文章:

    spring-boot - Spring Boot 社交登录和 Google Calendar API

    java - 通过 Flume 将 API 数据传输到 hadoop

    java - finally 添加 return 隐藏异常

    algorithm - 在 q/kdb+ 中,我可以加速 Kadane 的最大子数组问题算法吗?

    提交的应用程序包和实时应用程序包之间的性能差异

    javascript - 点亮元素 : best practise (or best performance) when creating many custom style rules vs a couple of dynamic rules inside a tiny web component?

    java - @Transactional 大大减慢了 Rest API

    spring-boot - Spring Boot 应用程序作为守护进程服务?

    java - java中Bencode字符串长度

    Java:如何向时间戳添加秒数?