【问题标题】:Persisting Data in a Twisted App在 Twisted App 中持久化数据
【发布时间】:2014-04-06 16:49:39
【问题描述】:

我正在尝试了解如何在 Twisted 应用程序中保存数据。假设我决定编写一个 Twisted 服务器:

  1. 接受入站 SMTP 请求
  2. 将消息发送到第 3 方系统进行修改
  3. 将修改后的消息中继到其目的地

一个典型的 Twisted 教程会让你使用 Deferreds 和回调来构建这个应用程序,大致如下:

  • 工厂处理入站请求
  • 每次收到完整的电子邮件时,都会向远程消息处理器发送一个调用,返回一个延迟
  • 如果在 modify 调用中出现任何问题,请添加替换原始消息的 errback。
  • 添加回调以将消息发送给收件人,收件人再次返回延迟。
  • 真正的服务器会添加/包含额外的调用/errbacks 以重试或通知发件人或诸如此类。再次为简单起见,假设我们认为这是可以接受的工作量并且只记录错误。

当然,如果发生崩溃/重启/其他情况,这不会保留任何数据。我知道一个解决方案涉及第 3 方持久数据存储(经常提到 RabbitMQ),并且可能会想出十几种随机方法来实现结果。

但是,我想有几种方法在 Twisted 应用中效果最好。他们看起来怎么样?他们如何存储(并在发生崩溃时恢复)进程中消息?

【问题讨论】:

  • 如果您提供一些您编写的简短示例代码 (sscce.org),并询问它有什么问题,而不仅仅是“您将如何做所有这些事情”,将会很有帮助?
  • 我绝对没有问如何实现所有这些东西。我继续阅读教程,并且(除了术语)伪代码几乎已经死了。例如,this tutorial 遵循几乎完全相同的逻辑流程。如果您将 main 中的调用替换为 SMTP 工厂(类似于 this setup)并添加 replacepoem_done 为 async relay_message,您将拥有一个工作服务器。
  • 问题是在这样的系统中更高级别的“如何持久化数据”(即提供交付可靠性)。我认识到答案可能是使用不同的架构(即用消息代理代替回调链),这就是为什么我以更笼统的“有没有更好的方法”结束。

标签: twisted


【解决方案1】:

如果您发现了这个问题,您可能已经知道 Twisted 是基于事件的。这听起来很简单,但答案中“最难”的部分是让持久性平台在我们需要的时候生成我们需要的事件。当然,您可以将数据保存在数据库或消息队列中,但某些平台不会自然生成事件。例如:

  • ZeroMQ 有(或至少有)no callback 用于新数据。它的持久性也相对较差。

在其他情况下,事件很容易,但可靠性是一个问题:

  • pgSQL 可以配置为使用 triggers 生成事件,但它们是一次性的,因此您无法恢复不完整的事件

隧道尽头的光似乎有点像 RabbitMQ。

  • RabbitMQ 可以persist 数据库中的消息在崩溃中幸免于难
  • 我们可以在两条腿(传入 SMTP 到 RabbitMQ 和 RabbitMQ 到传出 SMTP)上使用确认来确保应用程序是可靠的。重要的是,RabbitMQ 支持acknowledgements
  • 最后,一些 RabbitMQ 客户端提供了完整的异步支持(参见例如 pikatxampqpuka

RabbitMQ 客户端为我们提供一个基于事件的接口就足够了。

然而,在更理论的层面上,情况并非如此。事实上,尽管有上面的“通知”问题,ZeroMQ 有一个event-based client。即使我们的软件优雅地基于事件,我们也会遇到不是这样的系统。在这些情况下,我们别无选择,只能求助于polling。原则上,如果不是在实践中,我们只是向消息提供者查询消息。当我们耗尽当前队列时(如果没有消息则立即),我们使用callLater 命令在未来再次检查。它可能会让人觉得反模式,但它(无论如何据我所知)是处理这种特殊情况的正确方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多