【发布时间】:2018-01-17 08:35:20
【问题描述】:
我用.net core 2.0 在webapi 创建了一个小项目。我有一个控制器和一个用于插入、更新和读取文档的存储库。为了测试这一点,我创建了一个jmeter 测试来创建、更新和读取项目并使用 20 个并行线程启动它。问题是有时,读取操作或更新操作需要 4 秒。这是我的代码:
public class TransactionRepository : ITransactionRepository
{
private readonly MongoClient _mongoClient;
public TransactionRepository(string connectionString)
{
_mongoClient = new MongoClient(connectionString);
}
public async Task<TransactionResponse> RetrieveResponse(string id)
{
using (IAsyncCursor<TransactionRequest> cursor = await this._mongoClient
.GetDatabase("MyDatabase")
.GetCollection<TransactionRequest>("Transactions")
.FindAsync(t => t.Transaction.Id.Equals(id)))
{
while (await cursor.MoveNextAsync())
{
IEnumerable<TransactionRequest> documents = cursor.Current.ToList();
if (documents.Any())
{
var request = documents.First();
return new TransactionResponse { InternalId = request._id.ToString(), TransactionId = request.Transaction.Id};
}
Console.WriteLine(documents.Count());
}
}
return null;
}
public async Task<TransactionResponse> SaveAsync(TransactionRequest request)
{
await this._mongoClient
.GetDatabase("MyDatabase")
.GetCollection<TransactionRequest>("Transactions")
.InsertOneAsync(request, null, CancellationToken.None);
return new TransactionResponse
{
InternalId = request._id.ToString(),
TransactionId = request.Transaction.Id
};
}
public async Task<TransactionResponse> UpdateAsync(TransactionRequest request)
{
var findFilter = Builders<TransactionRequest>.Filter.Eq(t => t.Transaction.Id, request.Transaction.Id);
var updateSettings = Builders<TransactionRequest>
.Update
.Set(t => t.Transaction.Status, request.Transaction.Status)
.Set(t => t.Header.BusinessId, request.Header.BusinessId);
var findOptions = new FindOneAndUpdateOptions<TransactionRequest>
{
ReturnDocument = ReturnDocument.Before
};
var updatedRecord = await this._mongoClient
.GetDatabase("MyDatabase")
.GetCollection<TransactionRequest>("Transactions")
.FindOneAndUpdateAsync(
findFilter,
updateSettings,
findOptions);
string internalid = updatedRecord == null ? "-1" : updatedRecord._id.ToString();
string transactionId = updatedRecord == null ? "-1" : updatedRecord.Transaction.Id;
return new TransactionResponse {TransactionId = transactionId, InternalId = internalid };
}
}
startup.cs 中的代码:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddTransient<ITransactionRepository, TransactionRepository>(option => new TransactionRepository(Configuration["ConnectionString"]));
}
以及控制器代码:
[Route("api/requests")]
public class RequestsController : Controller
{
private readonly ITransactionRepository _repository;
public RequestsController(ITransactionRepository repository)
{
this._repository = repository;
}
[HttpPost]
[Route("")]
public async Task<TransactionResponse> Add([FromBody]TransactionRequest request)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var result = await this._repository.SaveAsync(request);
stopwatch.Stop();
Trace.WriteLine("#Trace# inserted item: " + stopwatch.ElapsedMilliseconds);
return result;
}
[HttpPost]
[Route("update")]
public async Task<TransactionResponse> Update([FromBody]TransactionRequest request)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var result = await this._repository.UpdateAsync(request);
stopwatch.Stop();
Trace.WriteLine("#Trace# updated item: " + stopwatch.ElapsedMilliseconds);
return result;
}
[HttpGet]
[Route("{id}")]
public async Task<TransactionResponse> Get([FromRoute]string id)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var result = await this._repository.RetrieveResponse(id);
stopwatch.Stop();
Trace.WriteLine("#Trace# read item: " + stopwatch.ElapsedMilliseconds);
return result;
}
}
这是我的模型类:
public class TransactionRequest
{
public ObjectId _id { get; set; }
public Header Header { get; set; }
public Transaction Transaction { get; set; }
}
public class Header
{
public string BusinessId { get; set; }
}
public class Transaction
{
public string Id { get; set; }
public string Status { get; set; }
}
public class TransactionResponse
{
public string InternalId { get; set; }
public string TransactionId { get; set; }
}
我需要在我的数据库上创建索引吗?更新操作或读取操作需要 3-4 秒是否正常?
【问题讨论】:
-
您是否分析过您的应用程序以验证 MongoDB 确实是瓶颈?
-
正如您在控制器代码中看到的那样,我正在使用秒表并且在那里我看到了这个
-
正如 Yuriy 和 Leonid 所提到的,您需要分析您的查询以找到瓶颈。
标签: c# asp.net-core mongodb-query asp.net-web-api2