我使用在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语句一起使用,对象在异常情况下处理.
正如一些帖子中所建议的,我已经检查了我的数据库的恢复模式,并验证它很简单.
我已手动杀死挂起的事务以回收日志文件空间,但几小时后它再次出现.我一直在观察它.
这种行为可能是什么原因?以及如何预防?
这个问题似乎是间歇性的,并且在生产中部署可能具有极高的风险:(
解决方法:
从Hangfire 1.5.0开始,Hangfire.SqlServer实现用事务包装后台作业的整个处理.在意外的进程关闭的情况下,先前的实现使用不可见性超时来提供至少一次处理保证而不需要事务.
我已经为队列处理实现了一个新模型,因为对于新用户来说存在很多混淆,特别是刚刚安装了Hangfire并在调试会话下使用它的用户.有很多问题,比如“为什么我的工作仍处于加工状态?”.我认为事务日志增长可能存在问题,但我不知道即使使用简单恢复模型也可能发生这种情况(请参阅this answer以了解原因).
看起来应该有一个开关,要使用的队列模型,基于事务(默认情况下)或基于不可见性超时.但是这个功能只能在1.6中使用,我还不知道任何ETA.
目前,您可以使用Hangfire.SqlServer.MSMQ或任何其他非RDBMS队列实现(请参阅Extensions页面). Hangfire的单独数据库也可能有所帮助,特别是如果您的应用程序更改了大量数据.
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!