当前位置: 首页 > 知识库问答 >
问题:

Cosmos SDK3容器可以是单例吗?

冯流觞
2023-03-14

我想减少Azure Cosmos DB SQL-API上的负载,它是从具有依赖注入的.NET Core Web API调用的。

在App Insights中,我注意到对Web API的每次调用都会导致对Cosmos的GetDatabase和GetCollection调用,当Cosmos负载较重时,这些调用可能需要5秒才能运行。

我已经将CosmosClient作为单例(例如这里的建议 - https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips-dotnet-sdk-v3-sql

但是,我找不到任何关于数据库容器对象是否也可以是单例的建议,因此它们是为对Web API的每个请求创建的。

我检查数据库和集合的存在(例如,遵循此处的建议 - https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.cosmos.cosmosclient.getdatabase?view=azure-dotnet#remarks 和 https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.cosmos.cosmosclient.getcontainer?view=azure-dotnet#remarks)

这意味着对于Web API的每个请求,将运行以下代码

var databaseResponse = await this.cosmosClient.CreateDatabaseIfNotExistsAsync(
    this.databaseConfiguration.DatabaseName,
    throughput: this.databaseConfiguration.DatabaseLevelThroughput);
var database = databaseResponse.Database;
var containerResponse = await database.CreateContainerIfNotExistsAsync(containerId, partitionKey);
var container = containerResponse.Container;

我能否将< code>Database和< code>Container设为单例,并将其添加到要像< code>CosmosClient一样注入的DI中,以便减少在App Insights中看到的GetDatabase和GetCollection的调用次数?

共有3个答案

王俊楚
2023-03-14

CreateDatabase aseIfNotExistsAsync应该只调用一次,因为它只是DB配置的设置步骤。

最好创建一个 DbService 来持久保存容器对象。并将 DbService 注入到每个服务中,而不是 DB 客户端

蓬化
2023-03-14

您不需要每次都调用<code>CreateIfNotExistsAsync是一个轻量级代理类。

除非您希望数据库和容器在某个时候被动态删除。

车靖琪
2023-03-14

根据最新的Microsoft留档,您创建了一个CosmosClient Service单例,它拥有您将使用的容器。也会影响容器单例。

首先,制定接口合同:

public interface ICosmosDbService
{
    // identify the database CRUD operations you need
}

其次,根据合同定义您的服务:

public class CosmosDbService : ICosmosDbService
{
    private Container _container;

    public CosmosDbService(CosmosClient dbClient, string databaseName, string containerName)
    {
        this._container = dbClient.GetContainer(databaseName, containerName);
    }
    
    // your database CRUD operations go here using the Container field(s)
}

第三,在Startup类中创建一个方法来返回CosmosClient:

private static async Task<CosmosDbService> InitializeCosmosClientAsync(IConfigurationSection cosmosConfig)
{
    var databaseName = cosmosConfig.GetSection("DatabaseName").Value;
    var containerName = cosmosConfig.GetSection("ContainerName").Value;
    var account = cosmosConfig.GetSection("Account").Value;
    var key = cosmosConfig.GetSection("Key").Value;
    var client = new Microsoft.Azure.Cosmos.CosmosClient(account, key);
    var database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
    await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
    return new CosmosDbService(client, databaseName, containerName);
}

最后,将您的CosmosClient添加到ServiceCollection:

public void ConfigureServices(IServiceCollection services)
{
    var cosmosConfig = this.Configuration.GetSection("CosmosDb");
    var cosmosClient = InitializeCosmosClientAsync(cosmosConfig).GetAwaiter().GetResult();
    services.AddSingleton<ICosmosDbService>(cosmosClient);
}

现在,你的 CosmosClient 只创建了一次(包含所有容器),每次通过依赖关系注入获取它时,它都会被重用。

 类似资料:
  • 是否可以将kubernetes作业作为我的kubernetes吊舱的初始容器? 我想只有在kubernetes作业成功达到完成状态后才启动kubernetes pod/部署。如果以上都不行,还有其他出路吗?我不能使用外部脚本检查等,然后启动我的pod。

  • 问题内容: 我只是从Docker开始,因此能够看到用于创建现有Docker映像的Dockerfile将非常有帮助。 即使图像是通过手动运行命令然后提交给标签来构建的,但出于学习目的和安全目的,能够看到图像的制作方式还是很不错的。 有没有一种方法可以提取Dockerfile或用于构建给定Docker映像的命令列表? 问题答案: 您有很大帮助。如果没有任何步骤涉及stdin,它甚至可以用于生成dock

  • 我刚刚开始使用Docker,能够看到用于创建现有Docker图像的Dockerfiles将非常有帮助。

  • 问题内容: 有两个容器A和B。一旦容器A启动,将执行一个过程,然后容器将停止。容器B只是一个Web应用程序(例如expressjs)。是否可以从容器B启动A? 问题答案: 可以向Docker授予容器访问权限,以便它可以在主机上生成其他容器。您可以通过在容器内部暴露docker套接字来执行此操作,例如: 现在,如果容器中有可用的客户端,则可以控制主机上的docker守护程序,并使用它生成“容器A”。

  • 问题内容: 我想创建一个包含一个或多个容器的Docker容器。Docker有可能吗? 问题答案: 在docker内部运行docker绝对是可能的。最主要的是,您将外部容器具有额外的特权(以开头),然后在该容器中安装docker。 查看此博客文章以获取更多信息:Docker-in-Docker。 本条目中描述了一种可能的用例。该博客介绍了如何在Jenkins Docker容器中构建Docker容器。

  • 当我得到一个Spring豆(通过getBean())时,有没有办法从java代码中验证豆子是否已经用范围=原型定义了? Spring配置: Java: sc 我可以实例化它两次并比较对象,但是我想避免不必要的对象创建。这个答案的反义词可能会有用:https://stackoverflow.com/a/9125610/156477