【问题标题】:How to cleanup the JdbcMetadataStore?如何清理 JdbcMetadataStore?
【发布时间】:2020-04-16 04:56:14
【问题描述】:

最初我们与 google Pub/Sub 的交流流程是这样的:

  1. 应用程序接受消息
  2. 检查是否在 idempotencyStore 中不存在
  3. 3.1 如果不存在 - 将其放入幂等存储(键是唯一标头的值,值是当前时间戳)
    3.2 如果存在 - 忽略此消息
  4. 处理完成后 - 发送确认
  5. 在确认成功回调中 - 从元数据存储中删除此消息

第 5 点是错误的,因为理论上我们可以在消息处理后得到重复的消息。此外,我们发现即使调用了成功的回调,有时消息也可能不会被删除(Message is received from Google Pub/Sub subscription again and again after acknowledge[Heisenbug])所以我们决定在消息处理后更新值并将时间戳替换为“FiNISHED”字符串

但迟早我们会遇到这张桌子会人满为患的情况。所以我们必须清理 MetaDataStore 中的消息。我们可以删除已处理且处理时间超过 1 天的邮件。

正如https://stackoverflow.com/a/51845202/2674303 的 cmets 中提到的,我可以在 metadataStore 表中添加额外的列,我可以在其中标记是否处理了消息。这根本不是问题。但是我怎样才能在我的清洁器中使用这个标志呢? MetadataStore 只有键和值

【问题讨论】:

    标签: spring-integration


    【解决方案1】:

    在确认成功回调中 - 从元数据存储中删除此消息

    我在这一步根本看不到任何原因。

    由于您说您在value 中存储了一个时间戳,这意味着您可以不时分析此表以删除绝对旧的条目。

    在我的一些项目中,我们每天在数据库中进行存档表的工作,以获得更好的主进程性能。对,只是因为我们不再需要旧数据了。出于这个原因,我们肯定会检查原始时间戳中的某些时间戳,以确定是否应该将其归档。我不会在处理后立即删除数据,因为有机会从外部系统重新传递。

    另一方面,为了获得更好的性能,我会在元数据表中添加带有timestamp 类型的额外索引列,并在每次更新或插入时通过触发器填充一个值。好吧,MetadataStore 只需插入来自MetadataStoreSelector 的条目:

    return this.metadataStore.putIfAbsent(key, value) == null;
    

    因此,您需要一个 on_insert 触发器来填充该日期列。这样您最终会知道是否需要删除条目。

    【讨论】:

    • 我需要在处理时填写其他字段。我需要在处理初始消息的那一刻填写它。例如,处理可能需要一个小时
    • 初始消息与幂等接收拦截器有何关系?看起来您尝试以错误的方式使用此模式。您在乞讨中的描述很好,但现在您谈论一些初始和其他东西。这令人困惑......
    • 好。不是说你已经可以接受我的回答,我们就可以去过年了吗? ;-)
    • 你的意思是在已经处理的情况下接受相同的消息就可以了吗?绝对错误但有时会发生(stackoverflow.com/questions/59391264/…)
    • 好吧,我不是说重新交付,我的意思是关于MetadataStore 的目的。我很困惑你想在FINISHED 标记之后收到相同的消息。但现在看起来IdempotentReceiver 模式是你的救星,你有一个不时清理表格的解决方案。
    猜你喜欢
    • 2011-04-21
    • 2017-01-02
    • 2015-12-31
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多