在生产中,我的 ASP.NET 项目运行良好,并在大约 12 秒内返回以下查询:
[HttpGet("suggest/{id1}/{id2}/{id3}")]
public async Task<List<int>> GetRecommendedShows(int id1, int id2, int id3)
{
List<int> showIds = new List<int>() { id1, id2, id3 };
// Fetch all shows from the database
var allShows = await _context.Shows
.Select(s => new { s.Id, s.VectorDouble })
.ToListAsync();
// Filter shows by the specified IDs
var selectedShows = allShows.Where(s => showIds.Contains(s.Id)).ToList();
if (selectedShows.Any())
{
// Calculate average vector
double[] averageVector = VectorEngine.CalculateAverageVector(selectedShows.Select(s => s.VectorDouble).ToList());
// Calculate similarities and get recommended show IDs
List<int> recommendedShowIds = VectorEngine.GetSimilarities(allShows.Select(s => new ShowInfo { Id = s.Id, VectorDouble = s.VectorDouble }).ToList(), averageVector, 8);
return recommendedShowIds;
}
else
{
// Return the input IDs if no shows are found
return showIds;
}
}
但是在 Ubuntu Cloud 生产服务器中,在 /api/input 进行搜索查询工作后(因此服务器工作),大约 20 秒后出现超时异常。这是堆栈跟踪:
FROM [Shows] AS [s]
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: WHERE [s].[Name] LIKE @__input_0_rewritten ESCAPE N'\'
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: ORDER BY CASE
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: WHEN [s].[Name] LIKE @__input_0_rewritten ESCAPE N'\' AND [s].[Name] IS NOT NULL THEN CAST(1 AS bit)
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: ELSE CAST(0 AS bit)
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: END DESC, CASE
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: WHEN @__input_0 = N'' THEN 0
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: ELSE CAST(CHARINDEX(@__input_0, [s].[Name]) AS int) - 1
Mar 16 18:53:14 debian-2gb-hel1-4 recommendit[26886]: END DESC
Mar 16 18:53:19 debian-2gb-hel1-4 recommendit[26886]: info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Mar 16 18:53:19 debian-2gb-hel1-4 recommendit[26886]: Executed DbCommand (41ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
Mar 16 18:53:19 debian-2gb-hel1-4 recommendit[26886]: SELECT [s].[Id], [s].[VectorDouble]
Mar 16 18:53:19 debian-2gb-hel1-4 recommendit[26886]: FROM [Shows] AS [s]
Mar 16 18:54:19 debian-2gb-hel1-4 recommendit[26886]: info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Mar 16 18:54:19 debian-2gb-hel1-4 recommendit[26886]: Executed DbCommand (123ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
Mar 16 18:54:19 debian-2gb-hel1-4 recommendit[26886]: SELECT [s].[Id], [s].[VectorDouble]
Mar 16 18:54:19 debian-2gb-hel1-4 recommendit[26886]: FROM [Shows] AS [s]
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: fail: Microsoft.EntityFrameworkCore.Query[10100]
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: An exception occurred while iterating over the results of a query for context type 'ShowPulse.Models.ShowContext'.
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: Microsoft.Data.SqlClient.SqlException (0x80131904): Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 2 - Connection was terminated: Connection was terminated)
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: ---> System.ComponentModel.Win32Exception (258): Unknown error 258
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: at Microsoft.Data.SqlClient.TdsParserStateObject.ThrowExceptionAndWarning(Boolean callerHasConnectionLock, Boolean asyncClose)
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: at Microsoft.Data.SqlClient.TdsParserStateObject.ReadAsyncCallbackCaptureException(TaskCompletionSource`1 source)
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: --- End of stack trace from previous location ---
Mar 16 18:55:47 debian-2gb-hel1-4 recommendit[26886]: at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeAsync(DbDataReader reader, IReadOnlyList`1 columns, CancellationToken cancellationToken)
at ShowPulse.Controllers.ShowsController.GetRecommendedShows(Int32 id1, Int32 id2, Int32 id3) in D:\consoleProjects\ShowPulse\Controllers\ShowsController.cs:line 6
完整日志在这里:https://pastebin.com/BX9UntZk
我尝试优化查询,因为我认为这是一个问题。
我还尝试增加超时时间:
builder.Services.AddDbContext<ShowContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("prodConnection"), sqlOptions =>
{
// Set the command timeout (in seconds)
sqlOptions.CommandTimeout(120);
// Enable retry on failure (if needed)
sqlOptions.EnableRetryOnFailure();
});
});
好的,您运行了一个具有 30 秒 CommandTimeout 的查询
3月16日18:54:19
CommandType='Text', CommandTimeout='30']已执行 DbCommand (123ms) [参数=[],
后来超时了。
3月16日18:55:47
执行超时已过期。超时时间 操作完成之前已过去或服务器未 回复了。
命令超时包括等待获取行,而不仅仅是等待第一行。因此,运行查询并获取所有行需要超过 30 秒的时间。
因此,您需要弄清楚为什么需要这么长时间,或者运行一个不需要太多时间来执行和返回结果的查询。