使用ConnectionMode.Direct未设置ConnectionProtocol的影响及错误排查
Azure Cosmos DB Direct连接模式下未设置ConnectionProtocol的问题
问题背景
我正在阅读Azure Cosmos DB连接策略相关内容,看到使用ConnectionMode = ConnectionMode.Direct时需要设置ConnectionProtocol。另有资料指出ConnectionMode.Direct默认适配TCP协议,因此应该将ConnectionProtocol设为Protocol.Tcp。但Protocol枚举的默认值是Https,我有几个疑问:
- 不设置
ConnectionProtocol属性时,是否会默认使用Https? - 如果默认用
Https,会引发什么问题吗? - 我们的代码没设置这个属性,近期出现
ServiceUnavailableException和SNAT端口耗尽错误,是否和这个配置有关?
相关业务代码
var connectionPolicy = new ConnectionPolicy { //ConnectionProtocol = Protocol.Tcp, // 未设置此属性! ConnectionMode = ConnectionMode.Direct, RequestTimeout = TimeSpan.FromSeconds(10), UserAgentSuffix = "ING", RetryOptions = new RetryOptions { MaxRetryAttemptsOnThrottledRequests = 5, MaxRetryWaitTimeInSeconds = 2 } }; var client = new DocumentClient(new Uri(endpoint), authKey, connectionPolicy, ConsistencyLevel.Session);
参考Protocol枚举定义
public enum Protocol { Https, Tcp }
问题解答
默认协议确认
是的,未显式设置ConnectionProtocol时,会默认使用Protocol.Https。C#中枚举的默认值为其定义的第一个成员,而Protocol枚举的第一个成员就是Https。Direct模式下使用Https的影响
ConnectionMode.Direct的设计初衷是通过TCP长连接实现低延迟、高吞吐量的通信。若配合Https协议使用,会产生以下问题:
- 连接性能损耗:Https基于HTTP无状态模型,每次请求需要重新完成TLS握手,相比TCP长连接的复用机制,额外开销显著,会降低整体请求处理效率。
- SNAT端口耗尽风险:Https的短连接特性会导致频繁创建、销毁TCP连接,每个连接都会占用一个SNAT端口。当请求量较大时,会快速耗尽可用SNAT端口,直接引发连接失败。
- 与当前报错的关联
你遇到的ServiceUnavailableException和SNAT端口耗尽错误,几乎可以确定和未设置ConnectionProtocol = Protocol.Tcp有关。Direct模式下误用Https产生的大量短连接,会快速消耗SNAT端口资源,导致新请求无法建立连接,最终触发服务不可用的异常。
修复方案
在ConnectionPolicy中显式指定TCP协议,确保Direct模式使用长连接:
var connectionPolicy = new ConnectionPolicy { ConnectionProtocol = Protocol.Tcp, // 新增此配置项 ConnectionMode = ConnectionMode.Direct, RequestTimeout = TimeSpan.FromSeconds(10), UserAgentSuffix = "ING", RetryOptions = new RetryOptions { MaxRetryAttemptsOnThrottledRequests = 5, MaxRetryWaitTimeInSeconds = 2 } };
内容的提问来源于stack exchange,提问作者David Klempfner
相关产品推荐
相关产品推荐

