在 Exchange 2010 中安排/排队大型电子邮件,推迟到延迟下降

在 Exchange 2010 中安排/排队大型电子邮件,推迟到延迟下降

我的挑战

我们在各个站点都设有 Exchange 服务器,船上也有。船舶在海上时通过卫星链路连接到我们的网络,但在港口时则切换到 WiFi 桥接。

由于延迟时间较长(超过 500 毫秒)且经常出现断线(例如,当船舶转向时),在海上尝试发送任何超过几兆字节的电子邮件都可能失败,并需要重试,直到达到限制。结果:电子邮件无法送达,每次尝试都会消耗卫星链路上宝贵的带宽。

一个“解决方案”是将电子邮件的最大大小限制为 5 MB,但这对用户来说并不友好,并且在端口上是一种不必要的限制。

粗略的想法

我更愿意做的是,将所有大于设定限制的电子邮件排队,以便在出海时稍后发送,同时立即发送所有小电子邮件。当时我在想我会定期 ping 我们数据中心的集线器传输服务器,当延迟低于 ~400 毫秒时,我会开始处理大型电子邮件队列。当延迟超过 400 毫秒时,我会堵住漏洞,让电子邮件再次排队。

现在,自 2003 版以来,我还没有真正接触过 Exchange。那时,您可以安排大型电子邮件以便稍后传送,因此我的想法是在 Exchange 2010 中做类似的事情,然后编写脚本来在“始终”和“从不”之间切换大型电子邮件的传送时间表。

障碍

创建这样的脚本应该不会太复杂,但是后来我读到我所依赖的功能已被 Exchange 2007 删除:

这是 Exchange 2003 中存在的一个功能,但在 Exchange 2007 中已被删除。它被设置在 SMTP 连接器上,并且“对超大邮件使用不同的传送时间”。

技术中心:在 Exchange 中,是否可以根据电子邮件大小安排电子邮件传送时间?

问题

这是真的吗? - 此功能在 Exchange 2010 中不再存在,还是只是变成了类似的东西,我可以用它来实现我的目标?如果是这样,那是什么?

是否有其他方法可以推迟某些 Exchange 服务器上大型电子邮件的投递?它可以基于时间表,甚至可能需要采取特定操作 - 我相当确定会有某种方法通过脚本触发投递,我只需要在船上将大型电子邮件放在单独的队列中。

非常感谢您对此的想法!:-)

编辑 #1:完善粗略想法

我偶然发现了两个 PowerShell CmdLets,我认为它们可以让我非常接近我的目标:

我玩弄了一会儿 Get-Message,想看看上面的命令可以处理什么类型的消息。

最重要的是,这些命令接受消息大小过滤器。此命令将列出当前服务器上大于 5 MB(5,242,880 字节)的排队消息:

get-message -Filter {Size -gt 5242880}

它似乎Get-Message只返回来自各种远程传递队列的消息。但是,在服务器内流动的消息(无论多么短暂)是否会出现在 Get/Sus​​pend/Resume-Message 会干扰的队列中?

如果没有的话,解决方案可以很简单,只需每隔几分钟运行一次计划脚本即可,如下所示(伪代码):

if ping_rtt > 400 Then
    Suspend-Message -Filter {Size -gt 5242880}
Else
    Resume-Message
EndIf

关注点/后续问题:

现在大多不相关 - 参见编辑#2。

Get-Message返回来自远程传递队列的消息 - 永远不会返回用于服务器内传递的消息?如果不是,远程传递队列的身份名称是否遵循某种模式,我可以使用它进行过滤?

这可以/应该通过自定义传输代理(如@longneck 所建议的)或事件接收器(如果此概念在 Exchange 2010 中仍然存在)来完成吗?

假设我每 5 分钟运行一次脚本,这仍然意味着发送大量消息可能会导致长达 5 分钟的问题,然后才会被暂停。我们的情况仍然比现在好,但这不是最佳选择。我可以将频率增加到每分钟,但这不是最优雅的解决方案。

即使我每 5 分钟仅检查一次往返时间(以节省卫星流量),每次提交到远程传送队列的消息时,我需要设置什么 Exchange 机制,以便根据最后记录的 RTT 进行检查,然后采取适当的措施?

编辑 #2:建议的解决方案

请允许我总结一下所提出的解决方案及其优缺点:

自定义传输代理

概念

  • 定期监控延迟,分类为高或低(阈值:400 毫秒?)
  • 通过自定义传输代理,当延迟分类发生变化时,暂停/恢复所有大于设定阈值的电子邮件
  • 通过自定义 TA,如果延迟较高,立即将后续提交的大消息置于“暂停”模式

优势

  • 当延迟较高时,大容量电子邮件永远不会被尝试发送

弱点

  • 没有内部开发技能(自我提醒:根据与外部开发人员签订的合同,源代码应属于我的公司)
  • 与 Exchange 绑定的第三方软件可能会在修补或更新时导致问题
  • 需要某种支持协议,以防出现问题(见上文)

中等大型消息

概念

  • 定期监控延迟,分类为高或低(阈值:400 毫秒?)
  • 根据延迟分类,通过脚本配置 Exchange 传输规则,以允许所有消息流动或将大消息转发给主持人
  • 当船舶停靠港口时,审核员队列中的消息,可能由人工审核

优势

  • 当延迟较高时,大容量电子邮件永远不会被尝试发送
  • 使用本机 Exchange 传输规则暂停邮件

弱点

  • 从表面上看,当延迟较低时,消息无法通过编程方式批准,因此每次船舶进港时都需要人工干预
  • 如果没有以程序化方式处理审核,可能会出现隐私问题

问题

  • 消息是否可以通过程序从版主邮箱中批准?如何批准?

计划的 PowerShell 命令

概念

  • 定期监控延迟,分类为高或低(阈值:400 毫秒?)
  • 只要延迟较高,就会频繁(每分钟?)暂停任何大型消息(Suspend-Message -Filter {Size -gt 5242880}
  • 当延迟降至较低水平时,恢复所有消息(Resume-Message

优势

  • 实现起来非常简单

弱点

  • 不是最优雅的解决方案
  • 只要Suspend-Message命令间隔时间足够长,就可以尝试传递每条新的大消息,但可能仍然会浪费一些带宽并造成拥塞(尽管与不执行任何操作相比非常短暂)

问题

  • 关于如何防止在Suspend-Message命令之间传递大消息的尝试,有什么想法吗?
  • Get-Message返回来自远程传递队列的消息 - 永远不会返回用于服务器内传递的消息?如果不是,远程传递队列的身份名称是否遵循某种模式,我可以使用它进行过滤?

编辑#3:前进的道路

在我的团队中提出建议的解决方案之后(包括 SMTP 代理,我未能将其包含在编辑#2 中),并且根据我自己的直觉,我们决定采用自定义 Exchange 传输代理。

我与几家咨询公司保持着联系,他们将告诉我如何解决这个问题以及需要花费多少钱。

如果你有外包编程任务的经验,欢迎给我的Stack Overflow 上的相关问题,因为我不知道。

答案1

为了按照您要求的方式解决问题,您可以使用Microsoft Exchange 传输代理 SDK。传输代理是基于事件的,因此 Exchange 会在收到消息时调用库中的函数。然后,您的库可以执行诸如保留消息之类的操作。如果您不具备内部技能来执行此操作,我相信您可以聘请开发人员为您编写它。

但我不认为这是一个很好的解决方案。作为您调查的替代方案,您可能希望研究诸如 SMTP 代理之类的低质量链接。正如您所发现的,SMTP 是一种糟糕的低质量链接协议,因为中断的连接会导致消息传输从头开始重新开始,而不是从中断的地方恢复。如果您要聘请开发人员,我会考虑编写一个服务器程序,该程序接受传入的 SMTP 连接并以可恢复的方式将消息发送到卫星连接另一端的同一程序的远程实例(可能通过 TCP 端口将大消息与小消息分开,以允许 WAN 加速器进行 QoS 处理)。然后,远程实例可以在收到完整消息后,通过 SMTP 完成消息的传递。

答案2

消息审核

一种可能不太理想的解决方案是使用传输规则将超过一定大小的邮件转发给发件人的经理或指定邮箱(在船舶的 Exchange 服务器上)进行审核。这样,如果邮件在海上,大邮件基本上可以在另一个邮箱中排队。当船舶抵达港口时,经理或指定审核员可以批准发送邮件。

缺点是:

  • 此规则始终处于启用状态,除非您手动禁用它(但可以通过脚本完成),因此即使在端口中,大邮件也会重定向到主持人邮箱
  • 所有大型邮件在发送前都需要有人进行手动审核,但你可以在规则中为特定事项添加例外情况
  • 另一个人可能会阅读外发邮件,出于隐私方面的考虑,这可能并不理想,但这取决于你的组织

一个好处是,你可以让一个人来决定是否应该发送一条消息,比如当用户试图发送一堆与工作无关的垃圾信息时,这些垃圾信息会毫无理由地阻塞连接。他们可以通过管理控制来纠正,比如指出一项政策并对他们进行惩罚,这样他们就不会再犯了。

Exchange 2010 传输规则

自定义脚本

回复:用于管理大型电子邮件的自定义脚本。我看到类似下面的内容,可以启用/禁用 Exchange 服务器上的发送连接器。缺点是所有邮件都保存在队列中,而不仅仅是大型邮件,但以下一些逻辑应该可行:

  1. 检查延迟。如果延迟较低,则启用发送连接器,取消暂停任何大消息,并等待 5 分钟(或其他任意时间长度)。如果延迟较高,则禁用发送连接器。
  2. 等5分钟。
  3. 5 分钟后,检查是否有大邮件并暂停它们。重新启用发送连接器,以便释放小的排队邮件,直到队列为空(您甚至可以一次循环处理 1 条邮件,以便在重新启用发送连接器后不会阻塞队列/WAN 链接)
  4. 禁用发送连接器并转到#1

这种逻辑并不完善,无法 100% 理解,但您明白了 - 将所有邮件排队,检查延迟,如果延迟过高则暂停大邮件,取消邮件排队,将所有邮件排队等。运行此类脚本的另一个缺点是,如果它崩溃或停止,您怎么知道在没有 IT 人员在船上的情况下重新初始化它?它可能会无限期地停止所有出站邮件(如果它在禁用发送连接器后停止),或者如果它只是让发送连接器保持启用状态并且脚本不再运行,您可能会失去对大邮件的控制。

SMTP 代理

尽管您已表示反对在 Exchange 之外处理任何消息,但在进一步考虑之后,我决定与 @longneck 一起使用某种类型的 SMTP 代理解决方案。即使 IIS SMTP 也具有延迟传递机制,而 Exchange 2010 似乎没有。您可以将大消息重定向到可以将它们存储在磁盘上的 IIS SMTP 服务器,然后首先检查延迟,让 IIS SMTP 服务器在延迟较低时通过脚本发送它们。如果您的调度机制卡住或停止,最坏的情况是大消息卡在磁盘上,但小消息继续发送。可能有比 IIS SMTP 更好的解决方案,我自己从未使用过它,但这只是一个例子。

在 IIS 7 中配置 SMTP 电子邮件

答案3

尝试了解一下 Exchange 2010 SP1 中引入的“消息限制”的新功能。这对您的用例可能非常有帮助。

http://technet.microsoft.com/en-us/library/bb232205(v=exchg.141).aspx

相关内容