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

abs*_*ask 14 exchange smtp exchange-2010 satellite

我的挑战

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

由于高延迟(500+ 毫秒)和不常见的丢失(例如,当船舶转弯时),尝试在海上发送任何超过几兆字节的电子邮件很可能会失败并重试直到限制已经达到。结果:电子邮件无法送达,每次尝试都会消耗卫星链接上的宝贵带宽。

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

粗略的想法

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

现在,我从 2003 版开始就没有真正接触过 Exchange。那时,您可以安排大型电子邮件以供以后发送,所以我的想法是在 Exchange 2010 中做一些类似的事情,然后编写一种方法来切换发送在“总是”和“从不”之间安排大型电子邮件。

障碍

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

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

TechCenter:是否可以根据 Exchange 中的大小安排电子邮件发送?

问题

这是真的吗?- 此功能是否不再存在于 Exchange 2010 中,或者它只是转换为类似的功能,我可以使用它来实现我的目标?如果是这样,是什么?

是否有另一种方法可以延迟在某些 Exchange 服务器上发送大型电子邮件?它可能基于时间表,甚至可能需要特定操作 - 我相当肯定会有某种方式通过脚本触发交付,我只需要在船上单独的队列中发送大量电子邮件。

您对此的想法将不胜感激!:-)

编辑 #1:提炼粗略的想法

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

我玩了一会儿 Get-Message,看看上面的命令会处理什么样的消息。

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

get-message -Filter {Size -gt 5242880}
Run Code Online (Sandbox Code Playgroud)

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

如果没有,解决方案可以像每隔几分钟的预定脚本一样简单,沿着(伪代码)行:

if ping_rtt > 400 Then
    Suspend-Message -Filter {Size -gt 5242880}
Else
    Resume-Message
EndIf
Run Code Online (Sandbox Code Playgroud)

疑虑/后续问题:

现在大多无关紧要 - 请参阅编辑#2。

Get-Message只返回远程传递队列中的消息-为服务器内交付从未消息?如果不是,远程传递队列的身份名称是否遵循某种模式,我可以使用该模式进行过滤?

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

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

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

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

请允许我总结一下提议的解决方案,以及我认为的利弊:

自定义传输代理

概念

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

优势

  • 当延迟很高时,从不尝试发送大型电子邮件

弱点

  • 没有内部开发技能(自我注意:作为与外部开发人员合同的一部分,源代码应属于我的公司)
  • 与 Exchange 相关的第 3 方软件在修补或更新时可能会导致问题
  • 需要某种支持协议,以防出现问题(见上文)

中等大消息

概念

  • 定期监控延迟,分类为高或低(阈值: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 上的相关问题提供反馈,因为我没有。

lon*_*eck 2

要按照您请求的方式解决问题,您可以使用Microsoft Exchange Transport Agent SDK编写自己的传输代理。传输代理是基于事件的,因此当收到邮件时,Exchange 将调用库中的函数。然后,您的图书馆可以执行诸如保留消息之类的操作。如果您内部没有执行此操作的技能,我相信您可以聘请开发人员为您编写它。

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