我正在将 cosmos db 模拟器作为 Docker 容器运行以进行测试。不幸的是我在连接它时遇到问题。执行时,如下代码
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(); // this is where the error occurs
var result = feedResponse.ToList();
return result.AsEnumerable();
}
正在抛出此异常
---> 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)
dbContext
只是一个暴露 IQueryable
的
Item
的类
internal class MyDbContext(CosmosClient cosmosClient)
{
private readonly Container items = cosmosClient.GetContainer("testdb", "items");
public IQueryable<Item> Items => items.GetItemLinqQueryable<Item>();
}
并且是这样注册的
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService<IOptions<PersistenceOptions>>();
return new CosmosClient(options.Value.ConnectionString);
});
按照文档 (https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-develop-emulator?tabs=docker) 将证书添加到 Windows 上的“受信任的根证书颁发机构”后-linux%2Ccsharp&pivots=api-nosql#export-the-emulators-tlsssl-certificate),我发现现在代码没有抛出异常,而是挂在var feedResponse = await query.ReadNextAsync();
上,之后什么也没有发生。我不知道如何检查问题所在以及为什么我无法获取数据。
)
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 数据库实例时,一切正常。我想知道是否有人对 cosmos db 模拟器有类似的经历。我应该注意一些限制吗?这是一个常见问题吗?
SSL证书问题 正确的证书安装:
确保证书安装正确。由于您已将证书添加到受信任的根证书颁发机构,请确保将其安装在正确的存储中(本地计算机用于服务器范围的信任,当前用户用于用户特定的信任)。
在 Docker 中验证证书:
检查 Docker 容器是否正确引用了已安装的证书。有时,容器可能无权访问主机的证书存储,您可能需要显式地使证书可供容器使用。 代码挂在 ReadNextAsync() 上
网络连接:
确保您的应用程序和 Docker 容器之间不存在网络问题。尝试从运行应用程序的位置对容器执行 ping 操作以确认连接。
防火墙或端口问题:
检查必要的端口是否已打开且未被防火墙阻止。 Cosmos DB 模拟器使用端口 8081 进行 HTTPS;确保此端口在您的 Docker 设置中正确映射并可访问。
Cosmos DB 模拟器配置:
验证 Cosmos DB 模拟器的配置。检查可能需要的任何环境变量或设置,尤其是在 Docker 容器中运行时。
调试应用程序:
使用调试工具单步执行代码并检查它到底挂在哪里。这可能会让您更深入地了解这是未返回的网络调用还是其他原因。
绕过 SSL 证书验证
临时解决方法:
您用来绕过 SSL 验证的方法通常应该作为临时解决方法。但出于安全原因,不建议用于生产。
检查 HttpClient 使用情况:
确保 Cosmos 客户端正确使用为绕过 SSL 验证而创建的 HttpClient 实例。调试以验证它是否被调用。
Docker 中 Cosmos DB 模拟器的限制 与完整的 Azure Cosmos DB 服务相比,模拟器有一些限制。例如,它可能不支持所有功能,或者在某些情况下的行为略有不同。 其他检查 版本兼容性:确保 Cosmos DB SDK 和模拟器的版本兼容。
日志记录:在应用程序中启用详细日志记录以捕获有关请求和响应的更多信息。 一般建议
使用真实 Azure 实例进行测试:由于在真实 Cosmos DB 实例上一切正常,因此可能存在一些特定于 Docker 中的模拟器设置的配置或网络相关问题。
最后,如果这些步骤无法解决问题,请考虑联系 Cosmos DB 社区或 Microsoft 支持人员以获取更具体的指导,因为他们可能知道 Docker 中运行的模拟器的细微差别。此外,查看模拟器的日志(如果有)可以更深入地了解可能出现的问题。