当我尝试在 MongoDB 集合中插入或更新文档时,我在应用程序的生产环境中遇到了 MongoDB C# 驱动程序的问题。偶尔(大约 1:100000 次),我会收到以下错误:
Thread static buffer is already in use. <--- Thread static buffer is already in use.
此问题不会持续发生,但似乎会在重负载或涉及多个线程时发生。
环境:
MongoDB C# 驱动程序版本:2.20
.NET 运行时:.NET Framework 和 .NET Core 7(我们有主应用程序 + 微服务。这两者都发生)
简化的代码片段:
public IMongoCollection<TDocument> GetMongoDbCollection<TDocument>(string collectionName = null){
IMongoCollection<TDocument> mongoCollection = null;
try
{
string databaseAddress = Vault.Get($"mongoDatabaseAddress");
string userName = Vault.Get($"mongoDbUserName");
string password = Vault.Get($"mongoDbPassword");
MongoClient mongoClient = new MongoClient($"mongodb+srv://{userName}:{password}@{databaseAddress}/<dbname>?retryWrites=true&w=majority&serverSelectionTimeoutMS=10000");
var database = mongoClient.GetDatabase("App");
mongoCollection = database.GetCollection<TDocument>(collectionName);
}
catch (Exception ex)
{
LoggerClient.Error(ex);
}
return mongoCollection;
}
public void InsertTransactions(List<Transaction)
{
try
{
var collection = this.GetMongoDbCollection<Transaction>(CurrentMongoCollection);
#region Edit transaction data before inserting
collection.InsertMany(encryptedTransactions);
}
catch (Exception ex)
{
LoggerClient.Error(ex);
}
}
以前有人遇到过这个问题吗?或者有人了解可能导致此问题的原因以及如何解决它吗?
谢谢您的帮助!
正如在this MongoDb 论坛中发布的那样,这可能与您对数据库连接的使用有关,而不是连接本身。
您发布的代码可能是一个示例,很难判断。尽管如此,我还是会通过检查依赖项注入或一般情况下您对连接的使用情况来开始调查。
我正在分享我为一个库编写的一段代码,我通过订阅集群事件来大量记录日志。您可以以此作为示例来构建深度日志记录系统并使用它来发现奇怪的事情,例如未关闭的数据库连接。
private static IMongoDatabase MongoDatabaseInstanceBuilder(MongoConnectionOptions options,
BaseMongoConnectionSecurityMode securityMode, IComponentContext context, string fullConnString)
{
var logger = context.Resolve<MongoDbLogger>().Logger;
logger.LogDebug("[MongoDB] - The MongoDB client will connect to {ConnString}", fullConnString);
var mongoClientSettings = MongoClientSettings.FromConnectionString(fullConnString);
logger.LogDebug("[MongoDB] - Obtaining MongoDB credentials. Security mode is {SecurityMode}",
securityMode.SecurityMode);
securityMode.AttachCredentials(mongoClientSettings, logger);
mongoClientSettings.ApplicationName = options.ApplicationName;
mongoClientSettings.MaxConnectionIdleTime = TimeSpan.FromSeconds(30);
mongoClientSettings.ReadPreference = ReadPreference.SecondaryPreferred;
mongoClientSettings.ClusterConfigurator = clusterBuilder =>
{
// events are heavy, let's subscribe only if debug is enabled
if (!logger.IsEnabled(LogLevel.Debug)) return;
clusterBuilder.Subscribe<ConnectionPoolOpenedEvent>(x =>
logger.LogDebug("[MongoDB] - Connection pool opened for cluster {ClusterId}",
x.ClusterId));
clusterBuilder.Subscribe<ConnectionPoolClosedEvent>(x =>
logger.LogDebug("[MongoDB] - Connection pool closed for cluster {ClusterId}",
x.ClusterId));
clusterBuilder.Subscribe<ConnectionPoolAddedConnectionEvent>(x =>
logger.LogDebug("[MongoDB] - Connection added to the pool. Connection id is {Id}",
x.ConnectionId.ServerId.ClusterId.Value));
clusterBuilder.Subscribe<ConnectionPoolRemovedConnectionEvent>(x =>
logger.LogDebug("[MongoDB] - Connection removed from the pool. Connection id is {Id}",
x.ConnectionId.ServerId.ClusterId.Value));
clusterBuilder.Subscribe<ConnectionPoolCheckedOutConnectionEvent>(x =>
logger.LogDebug("[MongoDB] - Connection checked out from the pool. Connection id is {Id}",
x.ConnectionId.ServerId.ClusterId.Value));
clusterBuilder.Subscribe<ConnectionPoolCheckedInConnectionEvent>(x =>
logger.LogDebug("[MongoDB] - Connection added back to the pool. Connection id is {Id}",
x.ConnectionId.ServerId.ClusterId.Value));
};
logger.LogDebug("[MongoDB] - Building MongoDB client instance");
var mongoClient = new MongoClient(mongoClientSettings);
logger.LogDebug("[MongoDB] - MongoDB client built. Returning connection to database {Database}",
options.Database);
return mongoClient.GetDatabase(options.Database);
}