Недавно я добавил аутентификацию в свою базу данных разработки, аутентификацию по базе данных «admin» и использование комбинации имени пользователя и пароля в строке подключения, например, mongodb://username:password@server:27017
. Почти сразу я начал видеть, что соединения не открываются, за исключением сообщения «Сервер отправил недопустимый одноразовый номер». Чтобы попытаться смягчить проблему, я посмотрел на время жизни моих объектов IMongoClient и перешел от создания множества таких объектов к использованию синглтона, внедренного в мои бизнес-службы с помощью библиотек Microsoft.Extensions.DependencyInjection. Это не решило проблему. Я установил MongoClient в моем Startup.cs, используя .AddSingleton<IMongoClient>(factory => new MongoClient(Configuration["Storage:MongoConnectionString"]))
. Я знаю, что строка подключения верна, поскольку она работает в MongoDB Compass, а также потому, что первая пара вызовов через драйвер работает успешно; проблема начинается, когда выполняется несколько одновременных вызовов.
Я использую MongoDB. NET драйвер, версия 2.11.0, под. NET Core 3.1.2. Проблема возникает в моей локальной среде с Windows 10, а также в моей промежуточной среде, работающей внутри Docker на VMware Photon.
В приложении есть два компонента, которые подключаются к MongoDB, оба из которых являются ASP. Net Основные приложения, одно из которых обслуживает API для интерактивного использования моего приложения, а другое запускает планировщик Quartz для фоновой обработки. Я использую MongoDB 4.4.0 Community внутри контейнера Docker.
Мои ссылки на включение драйвера:
<PackageReference Include="MongoDB.Bson" Version="2.11.0" />
<PackageReference Include="MongoDB.Driver" Version="2.11.0" />
<PackageReference Include="MongoDB.Driver.Core" Version="2.11.0" />
Согласно этот пост в MongoDB Jira site Я не первый, кто столкнулся с этой проблемой. Матиас Лоренцен предположил в вопросе о Jira, что он уменьшил количество ошибок, с которыми он сталкивается, с помощью различных исправлений, включая воссоздание пользователя, использование SCRAM-SHA-1 и увеличение максимального количества подключений, разрешенных на сервере. После внесения этих изменений проблема все еще возникает у меня.
Я предполагаю, что проблема связана с потоковой передачей при использовании в сочетании с аутентификацией базы данных. По очевидным причинам я не могу использовать этот код в производственной среде, отключив аутентификацию, чтобы обойти проблему, и в равной степени использование синхронной модели вместо asyn c кажется контрпродуктивным. Какие шаги я могу предпринять, чтобы попытаться решить проблемы с аутентификацией? Вероятно, это ошибка драйвера Mon go C#, или я просто неправильно его использую? 1018 *
Изменить: Минимальный воспроизводимый пример по запросу:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
namespace MongoDbIssueExample
{
internal class Program
{
private static IServiceProvider services;
private static IServiceProvider BuildDependencyInjector()
{
services = new ServiceCollection()
.AddSingleton<TestThingsService>()
.AddSingleton<IMongoClient>(factory => new MongoClient("mongodb://username:password@server:27017"))
.BuildServiceProvider();
return services;
}
private static async Task DoSeed()
{
var service = services.GetService<TestThingsService>();
// Don't do these async as we'll never get any data in...
service.CreateTestThings().Wait();
service.CreateOtherTestThings().Wait();
}
private static async Task DoTest()
{
var service = services.GetService<TestThingsService>();
var things = service.GetTestThings();
var otherThings = service.GetOtherTestThings();
Task.WaitAll(things, otherThings);
}
private static async Task Main(string[] args)
{
BuildDependencyInjector();
await DoTest();
}
}
public class TestThingsService
{
private readonly IMongoClient _client;
private readonly IMongoDatabase _database;
private readonly IMongoCollection<OtherTestThing> _otherTestThingsCollection;
private readonly IMongoCollection<TestThing> _testThingsCollection;
public TestThingsService(IMongoClient client)
{
_client = client;
_database = _client.GetDatabase("Things");
_testThingsCollection = _database.GetCollection<TestThing>("TestThings");
_otherTestThingsCollection = _database.GetCollection<OtherTestThing>("OtherTestThings");
}
public async Task CreateOtherTestThings()
{
for (var item = 1; item <= 10000; item++)
{
var testThing = new OtherTestThing {Id = item, Name = $"Other thing no. {item}", WhenCreated = DateTime.UtcNow};
await _otherTestThingsCollection.ReplaceOneAsync(f => f.Id == item, testThing, new ReplaceOptions {IsUpsert = true});
}
}
public async Task CreateTestThings()
{
for (var item = 1; item <= 10000; item++)
{
var testThing = new TestThing {Id = item, Name = $"Thing no. {item}", WhenCreated = DateTime.UtcNow};
await _testThingsCollection.ReplaceOneAsync(f => f.Id == item, testThing, new ReplaceOptions {IsUpsert = true});
}
}
public async Task<List<OtherTestThing>> GetOtherTestThings()
{
return await _otherTestThingsCollection.Find(_ => true).ToListAsync();
}
public async Task<List<TestThing>> GetTestThings()
{
return await _testThingsCollection.Find(_ => true).ToListAsync();
}
}
public class OtherTestThing
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime WhenCreated { get; set; }
}
public class TestThing
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime WhenCreated { get; set; }
}
}
Требуются следующие ссылки:
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.6" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.6" />
<PackageReference Include="MongoDB.Bson" Version="2.11.0" />
<PackageReference Include="MongoDB.Driver" Version="2.11.0" />
<PackageReference Include="MongoDB.Driver.Core" Version="2.11.0" />