.NET Core CosmosDB SDK:如何在应用启动后设置连接字符串?
问题背景与需求
我需要在运行于IoT设备上的.NET Core 7 Web应用中连接CosmosDB,但应用启动前无法获取连接字符串。为了安全且不在配置中存储连接字符串,计划通过Azure IoT Hub获取该信息。
常规场景下(非IoT设备的标准Web应用),我通常会在启动时从Azure密钥保管库读取连接字符串初始化CosmosDB单例服务,或使用Azure托管标识,但后者仅适用于Azure托管的应用,不适用于本地部署。
当前场景无法使用上述两种方案,需要实现一种方案:在单例服务初始化后、需要从CosmosDB获取数据时再传入连接字符串。
现有CosmosDB服务代码
public class CosmosDbService : ICosmosDbService { private static Database? Database; private readonly string _ohiAppSource; private readonly CosmosClient _cosmosClient; public readonly IConfiguration _configuration; public readonly ILogExtensionRepo _logExtensionRepo; public CosmosDbService( IConfiguration configuration, ILogExtensionRepo logExtensionRepo) { _configuration = configuration; _logExtensionRepo = logExtensionRepo; _ohiAppSource = _configuration["OhiAppSource"]!; _cosmosClient = new( // Fetching the connection string during service initialization is not an option for me here. connectionString: Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING")! ); CosmosClientOptions cosmosClientOptions = new() { MaxRetryAttemptsOnRateLimitedRequests = 3, MaxRetryWaitTimeOnRateLimitedRequests = TimeSpan.FromSeconds(60) }; } private string? LogData { get; set; } protected Database GetDatabase(string databaseName) { var database = _cosmosClient.GetDatabase(databaseName); return database; } protected Container GetContainer(string databaseName, string containerName, string partitionKey) { Database = _cosmosClient.CreateDatabaseIfNotExistsAsync(databaseName).GetAwaiter().GetResult(); if (String.IsNullOrEmpty(partitionKey)) { partitionKey = "/id"; // Default partition key if not specified. } var container_createIfNotExists = Database.CreateContainerIfNotExistsAsync(containerName, partitionKey, 400).GetAwaiter().GetResult(); return container_createIfNotExists; } }
后续优化思路(临时更新)
经过进一步研究,CosmosDB连接字符串不会频繁变更,但每次重新初始化CosmosClient都会导致首次请求耗时增加,产生性能损耗。同时IoT设备可能持续运行数月,密钥轮换不可避免,解决方案需要兼顾密钥轮换时的服务可用性。
结合单例服务的惰性特性(服务变量仅在首次实际使用时生效),计划:
- 启动时用无效值初始化Cosmos服务,在首次调用服务前及时更新为正确的连接字符串;
- 通过设备孪生更新属性获取最新连接信息,仅在检测到密钥变更时强制重新连接CosmosDB,以此减少不必要的性能损耗。
内容的提问来源于stack exchange,提问作者OJB1
相关产品推荐
相关产品推荐

