MS Graph API Webhook订阅与AWS API Gateway的神秘超时问题
Microsoft Graph API支持一种订阅资源类型,用于管理其Webhook实现,以向客户端传递变更通知。订阅功能适用于多种资源,包括Outlook消息——这完美契合了我管理O365中共享收件箱传入消息的需求。
高层次上,实现流程如下:
- 发起订阅请求,提供自定义的
notificationUrl
端点 - 响应通知验证请求
- 开始在处理程序上处理Webhook
- 定期更新上述订阅——最大过期时间取决于资源类型
实现方案
我的方法相当直接:将API Gateway连接到用于处理Webhook的Lambda函数,并使用CloudWatch规则触发订阅生命周期管理的Lambda。
重要的是,API Gateway背后的Lambda(Webhook请求/响应处理程序)除了处理实际的订阅通知外,还处理初始订阅验证。以下是验证过程要求的简要总结:
- 接受传入的HTTP POST请求,查询字符串中包含
validationToken
值 - 解码并转义令牌值
- 返回HTTP响应,包含:
- 正文包含解码后的令牌
- 状态码为200
- 内容类型为
text/plain
- 在10秒内交付
Outlook消息的最大过期时间为4230分钟(不到三天),因此我设置了CloudWatch规则每天运行一次以确保安全。这工作得非常完美——每天,订阅扩展Lambda都会被调用,Graph API会成功回复。整个往返时间,包括对Webhook监听器的验证请求,通常在一秒内完成。
神秘超时
上述实现按预期工作了数月——直到某一天,我开始在更新/扩展订阅时收到错误:
|
|
在我们端没有代码或基础设施变更的情况下,我开始通过手动运行订阅更新请求来调试,例如:
|
|
前几次尝试都失败了,错误与上述相同——然而,在第4或第5次尝试时成功了。在更多轮测试中,这种情况随机发生,最终以成功响应结束。
正如问题开始前几个月所经历的那样,成功的请求几乎在一秒内返回。值得注意的是,失败的请求确实在某种程度上似乎超时了,因为直到至少10秒过去后我才会收到HTTP 400错误。检查日志后,这些失败的请求似乎根本没有到达我们的基础设施。
假设
随机成功请求的性质,夹杂在从未到达我们端点的失败中,似乎暗示了某种类型的速率限制——无论是在Microsoft端,还是在AWS的API Gateway上强制执行。可能是随着时间的推移,与API Gateway集成的数量增加,达到了某个阈值,触发了从MS Graph API到API Gateway的连接限制。使用公共Webhook监听器测试工具进行的额外故障排除无法重现此问题,似乎进一步指向了API Gateway的特定问题。
Graph API支持拒绝提供帮助,建议我们没有适当的企业支持计划。个人认为,此问题的性质不应需要此类计划。如果MS支持的任何人读到本文,我邀请您查看,因为这可能影响us-east-1区域的其他实现。
解决方案
最终,我通过从API Gateway切换到公共ALB解决了此问题。供参考,这里有一个用于无服务器框架的方便CloudFormation片段。