我的挑战
我们在各个站点都有 Exchange 服务器,但也在船上。这些船只在海上时通过卫星链路连接到我们的网络,但在港口时切换到 WiFi 网桥。
由于高延迟(500+ 毫秒)和不常见的辍学(例如,当船转弯时),在海上尝试发送任何超过几兆字节的电子邮件很可能会失败并重试直到达到限制已经达到。结果:电子邮件没有送达,每次尝试都会消耗 sat 链接上宝贵的带宽。
一种“解决方案”是将电子邮件的最大大小限制为 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/Suspend/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 分钟检查一次往返时间(以节省 sat 流量),我需要设置什么 Exchange 机制,以便在每次提交到远程传递的消息时检查最后记录的 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 上的相关问题留下反馈,因为我没有。
消息审核
一个可能不理想的解决方案是使用传输规则将超过一定大小的邮件转发到发件人的经理或指定的邮箱(在船舶的 Exchange 服务器上)以进行审核。这样,如果他们在海上,大邮件基本上可以在另一个邮箱中排队。当船到达港口时,经理或指定的主持人可以批准他们交付。
缺点是:
一个好处是,你可以让一个人来决定是否应该发送一条消息,例如,如果用户试图发送一堆与工作无关的废话,这些废话只会无缘无故地中断连接。他们可以通过行政控制来纠正,比如指出一项政策并将他们拍在手腕上,这样他们就不会再犯了。
Exchange 2010 传输规则
自定义脚本
回复:管理大型电子邮件的自定义脚本。我可以看到类似下面的内容,它会在 Exchange 服务器上启用/禁用您的发送连接器。缺点是所有邮件都在队列中,而不仅仅是大邮件,但这些方面的一些逻辑应该有效:
这个逻辑并没有完全完善到 100% 有意义,但是你明白了 - 对所有邮件进行排队,检查延迟,如果它很高则暂停大消息,取消排队邮件,对所有邮件进行排队等。运行的另一个缺点像这样的脚本如果崩溃或停止,您怎么知道在船上没有 IT 人员的情况下重新初始化它?它可能会无限期地停止所有出站邮件(如果它在禁用发送连接器后停止),或者如果它只是启用发送连接器并且脚本不再运行,您可能会失去对大邮件的控制。
SMTP 代理
尽管您已表示反对在 Exchange 之外处理任何消息,但在进一步考虑之后,我决定与@longneck 一起使用某种类型的 SMTP 代理解决方案。即使是 IIS SMTP 也有延迟传递机制,而 Exchange 2010 似乎没有。您可以将大消息重定向到可以将它们存储在磁盘上的 IIS SMTP 服务器,并且首先检查延迟,让 IIS SMTP 服务器在延迟较低时通过脚本发送它们。如果您的调度机制卡住或停止,最坏的情况是大消息卡在磁盘上,但小消息继续发送。可能有比 IIS SMTP 更好的解决方案,我自己从未使用过,但这只是一个例子。
在 IIS 7 中配置 SMTP 电子邮件
尝试查看 Exchange 2010 SP1 引入的“消息限制”的新功能。它可能对您的用例非常有帮助。
http://technet.microsoft.com/en-us/library/bb232205(v=exchg.141).aspx
要按照您要求的方式解决问题,您可以使用Microsoft Exchange Transport Agent SDK编写自己的传输代理。传输代理是基于事件的,因此 Exchange 将在收到消息时调用库中的函数。然后你的图书馆可以做一些事情,比如保留信息。如果您不具备执行此操作的内部技能,我相信您可以聘请开发人员为您编写。
但我不认为这是一个很好的解决方案。作为您调查的替代方案,您可能需要查看诸如 SMTP 代理之类的低质量链接。正如您所发现的,SMTP 对于低质量链接来说是一个可怕的协议,因为中断的连接会导致消息传输从头开始重新开始,而不是从中断的地方继续。如果你打算为某事雇用一名开发人员,我会考虑编写一个服务器程序,它接受传入的 SMTP 连接,并以可恢复的方式将消息发送到卫星连接另一端的同一程序的远程实例(可能通过 TCP 端口将大消息与小消息分开,以允许 WAN 加速器进行 QoS 处理)。然后,远程实例可以在收到完整消息后,