我使用在IIS中运行的MVC开发了一个Hangfire应用程序,它工作得很好,直到我看到我的SQL Server日志文件的大小,一夜之间增长了40 GB!
根据我们DBA的信息,有一个长时间运行的事务,带有以下SQL语句(我有2个hangfire队列) -
(@queues1 nvarchar(4000),@queues2 nvarchar(4000),@timeout float)
delete top (1) from [HangFire].JobQueue with (readpast, updlock, rowlock)
output DELETED.Id, DELETED.JobId, DELETED.Queue
where (FetchedAt is null or FetchedAt < DATEADD(second, @timeout, GETUTCDATE()))
and Queue in (@queues1,@queues2)
在探索Hangfire库时,我发现它用于出列作业,并执行一项非常简单的任务,不应该花费任何重要时间。
我找不到任何可能导致此错误的内容。事件与using
语句一起使用,如果发生异常,对象为Disposed
。
正如一些帖子中所建议的那样,我已经检查了数据库的恢复模式,并确认它很简单。
我已经手动杀死了挂起的事务以回收日志文件空间,但几小时后它再次出现。我一直在观察它。
这种行为可能是什么原因?以及如何预防?
问题似乎是间歇性的,并且在生产中部署可能具有极高的风险:(
答案 0 :(得分:5)
从Hangfire 1.5.0开始,sizeof
实现使用事务包装后台作业的整个处理。以前的实现使用不可见超时来提供至少一次处理保证,而不需要事务,以防意外进程关闭。
我已经为队列处理实现了一个新模型,因为对于新用户来说存在很多混淆,特别是刚刚安装了Hangfire并在调试会话下使用它的用户。有很多问题,比如“为什么我的工作仍处于处理状态?”。我认为事务日志增长可能存在问题,但我不知道即使使用简单恢复模型也可能发生这种情况(请参阅this answer了解原因)。
看起来应该有一个交换机,要使用的队列模型,基于事务(默认情况下)或基于隐身超时。但是这个功能只能在1.6中使用,我还不知道任何ETA。
目前,您可以使用Hangfire.SqlServer.MSMQ或任何其他非RDBMS队列实施(请参阅Extensions页面)。 Hangfire的单独数据库也可能有所帮助,特别是如果您的应用程序更改了大量数据。