如何避免Office 365/EWS中的连接限流问题?
解决Exchange Service OAuth刷新导致连接数超限问题
复用Service对象,只更新凭据不重建实例
你现在的问题大概率是刷新令牌时不小心创建了新的Exchange Service实例,而非单纯更新凭据。service.Credentials = new OAuthCredentials(result.token)这个操作本身不会触发新连接创建,只要你全程复用同一个(或固定数量的)Service对象,连接池就会复用已有连接,不会持续涨数。核心是不要每次刷新令牌就新建Service实例,维护全局单例或实例池即可。限制HTTP连接池的最大连接数
EWS底层依赖的HTTP连接池可以手动配置上限,直接卡住不超过Office 365的27个限制:- .NET Framework:修改配置文件,给Office 365域名设连接数上限:
<configuration> <system.net> <connectionManagement> <add address="https://outlook.office365.com" maxconnection="25"/> </connectionManagement> </system.net> </configuration> - .NET Core/5+:自定义HttpClientHandler并设置最大连接数,再绑定到Service对象:
var handler = new HttpClientHandler { MaxConnectionsPerServer = 25 }; service.HttpClient = new HttpClient(handler);
- .NET Framework:修改配置文件,给Office 365域名设连接数上限:
调整令牌刷新时机,减少不必要操作
令牌有效期65分钟,没必要每30分钟就刷新,改成过期前5-10分钟再刷新(比如每60分钟一次),减少凭据更新的频率,避免连接池出现不必要的波动。主动释放闲置连接(旧版EWS适用)
如果用的是旧版EWS API(基于HttpWebRequest),可以在批量操作完成后,显式释放闲置连接:ServicePointManager.FindServicePoint(new Uri(service.Url)).CloseConnectionGroup("");注意别在请求进行中调用,会中断正在执行的操作。
优化拉取订阅的超时参数
要是用了拉取订阅,把超时设成最大30分钟的长轮询,这样单次请求会保持连接,减少短连接创建:var pullSubscription = service.SubscribeToPullNotifications( folderIds, 1800000, // 30分钟超时,单位毫秒 null, eventTypes );长轮询能复用连接,大幅降低连接池的连接数。
内容的提问来源于stack exchange,提问作者John in 't Veld
相关产品推荐
相关产品推荐

