我正在使用ASP.NET Core 2.2 Web API多租户应用程序。该应用程序使用Hangfire运行后台任务。我们正在尝试提高应用程序的性能。
它将所有作业存储在单独的数据库(Hangfire数据库)中,但这会影响API性能。我已跟踪API请求以检查请求时间,这是结果:
这里是代码
public async Task<string> AddUser(UserModel user)
{
CreateUserInBackgorund(user);
// removed code
return "some status";
}
[Queue(Constants.Critical)]
public void CreateUserInBackgorund(UserModel user)
{
BackgroundJob.Enqueue(() => CreateUser(user));
}
public async Task CreateUser(UserModel user)
{
try
{
//Other code
}
catch (Exception ex)
{
_logger.Error(ex.Message, ex);
}
}
跟踪日志似乎表明后台调用会影响请求的性能。有没有办法减少时间或使用其他方法?
由于缺乏信息,因此建议您检查哪些内容:
SQL Server THREADPOOL Waits而不是C#代码可能存在问题。https://www.sqlskills.com/help/waits/threadpool/另外,通过检查SQL Server工具,您可能会获得有关长时间运行的查询的更多信息。https://www.sqlshack.com/how-to-identify-slow-running-queries-in-sql-server/请注意,每个事务都会锁定表,如果队列中有很多事务,它们也可能会大大降低性能。
在[Queue(Constants.Critical)]中,肯定有逻辑,主请求线程需要在开始执行execute方法之前执行。尝试类似的事情也是合理的Task.Run(()=> CreateUserInBackgorund(user));在AddUser(UserModel用户)中并检查它会如何影响。
以这种方式使用后台作业是很奇怪的做法。通常,后台作业被用作未由用户执行的业务逻辑部分的调度程序,以及当某些逻辑需要在特定的时间或时间段内执行的情况下。例如。每天或每周,每月等计算一些内容。如果您仅使用后台作业只是为了将响应更快地传递给用户,那么最好使用一些队列/服务总线,例如RabbitMQ用于消息传递事件,然后添加将按需执行on_message_received事件所需任务的侦听器。因此,没有必要将hangfire用于尚未真正设计的事情以及大量用户请求。它将有可能显着减少对其数据库进行的与hangfire相关的请求的数量,以及对SQL Server的总体压力。