Cosmos DB模拟器Docker容器连接问题:SSL与超时异常排查
Docker运行Cosmos DB模拟器连接问题排查
问题场景
为测试目的使用Docker容器运行Cosmos DB模拟器,但连接时遇到异常。执行以下查询代码:
public async Task<IEnumerable<Item>> GetItemsAsync(int offset = 0, CancellationToken cancellationToken = default) { var query = dbContext.Items .OrderBy(x => x.LastReadAt) .ThenByDescending(x => x.CreatedAt) .Skip(offset) .Take(10) .ToFeedIterator(); var feedResponse = await query.ReadNextAsync(); // 此处触发错误 var result = feedResponse.ToList(); return result.AsEnumerable(); }
初始异常
抛出SSL证书信任错误:
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. [2024-01-21T18:28:23.229Z] ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot [2024-01-21T18:28:23.230Z] at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
相关代码定义
MyDbContext类:
internal class MyDbContext(CosmosClient cosmosClient) { private readonly Container items = cosmosClient.GetContainer("testdb", "items"); public IQueryable<Item> Items => items.GetItemLinqQueryable<Item>(); }
CosmosClient注册代码:
services.AddSingleton(serviceProvider => { var options = serviceProvider.GetRequiredService<IOptions<PersistenceOptions>>(); return new CosmosClient(options.Value.ConnectionString); });
后续排查
将模拟器证书添加到Windows“受信任根证书颁发机构”后,SSL错误消失,但代码在ReadNextAsync处挂起,无法获取数据。尝试绕过SSL验证的注册方式,问题依旧:
services.AddSingleton(serviceProvider => { var options = serviceProvider.GetRequiredService<IOptions<PersistenceOptions>>(); return new CosmosClient(options.Value.ConnectionString, new CosmosClientOptions { HttpClientFactory = () => { HttpMessageHandler httpMessageHandler = new HttpClientHandler() { ServerCertificateCustomValidationCallback = (req, cert, chain, errors) => true }; return new HttpClient(httpMessageHandler); }, ConnectionMode = ConnectionMode.Gateway } });
连接Azure上的真实Cosmos DB实例一切正常。
更新:挂起后最终抛出的异常
---> Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: ServiceUnavailable (503); Substatus: 20003; ActivityId: 00000000-0000-0000-0000-000000000000; Reason: (GatewayStoreClient Request Timeout. Start Time UTC:21/01/2024 20:33:50; Total Duration:45892.3326 Ms; Request Timeout 20000 Ms; Http Client Timeout:65000 Ms; Activity id: 00000000-0000-0000-0000-000000000000;); [2024-01-21T20:34:36.408Z] ---> System.Threading.Tasks.TaskCanceledException: The operation was canceled. [2024-01-21T20:34:36.408Z] ---> System.Threading.Tasks.TaskCanceledException: The operation was canceled. [2024-01-21T20:34:36.408Z] ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request.. [2024-01-21T20:34:36.409Z] ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
问题解决与注意事项
核心修复步骤
修正CosmosClient SSL绕过配置
原配置中通过HttpClientFactory返回HttpClient的方式不正确,应该直接设置HttpClientHandler属性:services.AddSingleton(serviceProvider => { var options = serviceProvider.GetRequiredService<IOptions<PersistenceOptions>>(); var cosmosOptions = new CosmosClientOptions { HttpClientHandler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (_, _, _, _) => true }, ConnectionMode = ConnectionMode.Gateway }; return new CosmosClient(options.Value.ConnectionString, cosmosOptions); });确保Docker容器正确启动
启动容器时必须映射完整端口并分配足够资源,命令示例:docker run -p 8081:8081 -p 10250:10250 -p 10251:10251 -p 10252:10252 -p 10253:10253 -p 10254:10254 -m 3g --cpus=2.0 -e AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE=true mcr.microsoft.com/cosmosdb/windows/azure-cosmos-emulator- 必须分配至少3GB内存、2核CPU,否则会出现503超时
- 所有必要端口必须映射,缺一不可
验证网络与连接字符串
- 连接字符串的Endpoint必须是
https://localhost:8081(本机Docker)或Docker主机的IP,不能用容器内部地址 - 检查防火墙是否允许8081端口的出入请求
- 连接字符串的Endpoint必须是
常见限制
- Docker版Cosmos DB模拟器仅支持Windows容器,WSL2环境需切换到Windows容器模式
- 模拟器性能远低于真实Cosmos DB,不适合压测
- 仅支持固定的默认密钥,无法自定义
- 部分高级功能(如全局分布、多区域写入)不支持
内容的提问来源于stack exchange,提问作者Alienown
相关产品推荐
相关产品推荐

