[英]Slow responses from MongoDb after concurrent requests via ASP.NET Core REST API
I'm running a web service based on ASP.NET Core 2.2.我正在运行基于 ASP.NET Core 2.2 的 Web 服务。 External clients call the REST API in regular intervalls.
外部客户端定期调用 REST API。 So it is possible, that the API is hit with about 50 nearly concurrent requests (every 10 to 40 min.).
因此,API 可能会遇到大约 50 个几乎并发的请求(每 10 到 40 分钟)。
Problem: Some minutes after the concurrent requests the service's response time is high.问题:并发请求几分钟后,服务的响应时间很长。 The response time increased from < 1 s (for single requests) to 40 sec.
响应时间从 < 1 秒(对于单个请求)增加到 40 秒。
Remarks:评论:
mongostat
shows about 90 open connections. mongostat
的输出显示大约 90 个打开的连接。 Questions:问题:
EDIT: Using the ClusterConfigurator of the MongoClientSettings available from the MongoDB Driver package for C# I measured an increase of duration of a query up to 00:00:04.5022352 seconds (from 00:00:00.0005432).编辑:使用 C# 的 MongoDB 驱动程序包中可用的 MongoClientSettings 的 ClusterConfigurator 我测量了查询持续时间的增加,最多 00:00:04.5022352 秒(从 00:00:00.0005432)。
I noticed that opLatencies reads are increasing during 50 nearly concurrent requests: opLatencies.reads.latency: from 68723 to 202886, opLatencies.reads.ops: from 449 to 1053我注意到 opLatencies 读取在 50 个几乎并发的请求中增加:opLatencies.reads.latency:从 68723 到 202886,opLatencies.reads.ops:从 449 到 1053
Background:背景:
The MongoClient
is created in following class: MongoClient
在以下类中创建:
public class MongoDbContext : IContext {
private readonly MongoUrl _url;
private MongoClient _client;
private IMongoDatabase _db;
public MongoDbContext (string connectionString) {
_url = MongoUrl.Create (connectionString);
}
public IMongoDatabase GetDatabase () {
return _db ?? (_db = GetClient ().GetDatabase (_url.DatabaseName));
}
public MongoClient GetClient () {
return _client ?? (_client = new MongoClient (_url));
}
}
The context is injected in the Startup.cs and used in serveral repositories.上下文被注入 Startup.cs 并在多个存储库中使用。
//... Startup.cs
var context = new MongoDbContext(connectionString);
services.AddSingleton<IContext>(context);
// Other services and repositories ...
services.AddTransient<IWeatherRepository, WeatherRepository>();
The repositories use following base class:存储库使用以下基类:
public abstract class MongoDbRepository<T> : IRepository<T> where T : Entity<long> {
private IMongoCollection<T> _collection { get; set; }
protected IContext Context { get; set; }
protected abstract IMongoCollection<T> GetCollection ();
protected IMongoCollection<T> Collection {
get { return _collection ?? (_collection = GetCollection ()); }
set { _collection = value; }
}
public MongoDbRepository (IContext context) {
Context = context;
}
/// ...
public async Task<IEnumerable<T>> Find (Expression<Func<T, bool>> filter) {
return await Collection.Find (filter).ToListAsync ();
}
}
你有没有试过对这些操作使用异步方法可能会帮助你改善并发操作响应。(在数据库上下文中)
I would not recommend to use Singleton
for DB Context.我不建议将
Singleton
用于 DB Context。 This object should be released as soon as it is not needed.该对象在不需要时应立即释放。 Use
Scoped
instead, it will be shared among your repositories within request and then will be released:改用
Scoped
,它将在请求中的存储库之间共享,然后将被释放:
services.AddScoped<IContext, MongoDbContext>(provider => new MongoDbContext(connectionString));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.