自主开发的Delphi SMTP中继服务器的高可用性?

时间:2012-10-01 08:55:46

标签: mysql delphi queue high-availability

我想知道为自行开发的SMTP中继服务器实现高可用性的最佳方法是什么,每秒需要处理30-100封电子邮件。

该服务器本质上做的是对各种smtp客户端进行身份验证,然后中继到特定的邮件服务器并处理错误,例如:邮件服务器不可用等因此,需要一个队列来包含电子邮件消息,其中可能包含大附件。为了实现高可用性,系统应支持群集,我可以将Windows群集用于主/辅活动群集。

我认为电子邮件队列可以驻留在:

  1. 记忆(这种方法出于显而易见的原因。)
  2. RDMS
  3. 文件(我相信这是IIS虚拟SMTP使用的?)
  4. 嵌入式数据库,例如SQLite
  5. SQLite和文件的混合
  6. 需要安装和配置的一些奇特的第三方队列产品?
  7. 高可用性的常用方法是使用诸如MySQL的RDBMS,但是使用RDBMS作为消息队列会显着降低性能,除非我有一个强大的MySQL服务器。最重要的是,我将不得不实现MySQL集群。另外,我在某处读到没有人应该使用MySQL作为队列 - http://www.engineyard.com/blog/2011/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-you/

    或者,我可以使用SQLite + File,这可能是最快的(除了纯内存)和最容易部署的方法(无需安装),但SQLite没有集群,因此如果服务器崩溃,则发送未发送的消息可能仍然会丢失。

1 个答案:

答案 0 :(得分:1)

2和4是一回事--RDBMS。这是一个糟糕的选择,因为RDBMS针对的是复杂的查询,并且必须保持自己的时间。收集垃圾,重建索引,增加db文件......下次INSERT任何时候都会缓慢甚至完全阻塞一段时间。即使在像Firebird和Postgress这样的基于版本的引擎中也是如此。使用基于锁的MS SQL和SQLite更是如此。

如果你希望它可靠,那么你可能会将它作为几个狭隘的任务工作者来实现,这也可以让你使用OmniThreaLibrary或AsyncCalls进行多线程处理。

“Sink”工作者应该将邮件接收到内存缓冲区,也许从表头中提取一些元数据并将其存储到当前的接收队列中。由于Win32线程很昂贵,所以让一个线程同时使用几个套接字,一个Erlang / Scala的la“actors”框架会很好。你甚至可以将一些线程移动到像qmail设计的单独的exe,以使崩溃本地化。在未来甚至跨越计算机集群。

“Dumper”将占用一个孤立的队列并将其转换为连续的非SQL文件(由于HDD抖动数据文件系统 - 数据文件系统-...,您不需要单独的文件),然后他会切换队列:隔离上述接收队列以进行转储,并将其替换为刚清空的队列。 “有两个队列并切换它们”是用于例如3D游戏中的常见“页面翻转”特征。 TForm.DoubleBuffering类似但减少了概念。顺便说一句,你还应该有两个文件夹,如上面的内存中队列。

“dbkeeper”同样会采用其中一个文件转储,将其移入RDBMS并切换。

您必须围绕这些切换活动设置这些工作人员之间的通信。每个队列都要接收或转储,以最大限度地减少并发访问(频率和寿命)。

你可能会读到有关邮件发送者设计的内容 - 它的维护者在踩到一个或另一个瓶颈后几次重构了他的软件,这也可以让你估计这些瓶颈何时开始影响性能。


但实际上,为什么不使用一些现成的和经过测试的服务器呢?