Hangfire.SqlServer.MSMQ extension changes the way Hangfire handles job queues. Default implementation uses regular SQL Server tables to organize queues, and this extensions uses transactional MSMQ queues to process jobs. Please note that starting from 1.7.0 it’s possible to use TimeSpan.Zero
as a polling delay in Hangfire.SqlServer, so think twice before using MSMQ.
MSMQ support for SQL Server job storage implementation, like other Hangfire extensions, is a NuGet package. So, you can install it using NuGet Package Manager Console window:
PM> Install-Package Hangfire.SqlServer.Msmq
To use MSMQ queues, you should do the following steps:
SqlServerStorage
instance.If you are using only default queue, call the UseMsmqQueues
method just after UseSqlServerStorage
method call and pass the path pattern as an argument.
GlobalConfiguration.Configuration
.UseSqlServerStorage("<connection string or its name>")
.UseMsmqQueues(@"FormatName:Direct=OS:localhost\hangfire-{0}");
To use multiple queues, you should pass them explicitly:
GlobalConfiguration.Configuration
.UseSqlServerStorage("<connection string or its name>")
.UseMsmqQueues(@"FormatName:Direct=OS:localhost\hangfire-{0}", "critical", "default");
If you have a fresh installation, just use the UseMsmqQueues
method. Otherwise, your system may contain unprocessed jobs in SQL Server. Since one Hangfire Server instance can not process job from different queues, you should deploy multiple instances of Hangfire Server, one listens only MSMQ queues, another – only SQL Server queues. When the latter finish its work (you can see this in Dashboard – your SQL Server queues will be removed), you can remove it safely.
If you are using default queue only, do this:
/* This server will process only SQL Server table queues, i.e. old jobs */
var oldStorage = new SqlServerStorage("<connection string or its name>");
var oldOptions = new BackgroundJobServerOptions
{
ServerName = "OldQueueServer" // Pass this to differentiate this server from the next one
};
app.UseHangfireServer(oldOptions, oldStorage);
/* This server will process only MSMQ queues, i.e. new jobs */
GlobalConfiguration.Configuration
.UseSqlServerStorage("<connection string or its name>")
.UseMsmqQueues(@"FormatName:Direct=OS:localhost\hangfire-{0}");
app.UseHangfireServer();
If you use multiple queues, do this:
/* This server will process only SQL Server table queues, i.e. old jobs */
var oldStorage = new SqlServerStorage("<connection string>");
var oldOptions = new BackgroundJobServerOptions
{
Queues = new [] { "critical", "default" }, // Include this line only if you have multiple queues
ServerName = "OldQueueServer" // Pass this to differentiate this server from the next one
};
app.UseHangfireServer(oldOptions, oldStorage);
/* This server will process only MSMQ queues, i.e. new jobs */
GlobalConfiguration.Configuration
.UseSqlServerStorage("<connection string or its name>")
.UseMsmqQueues(@"FormatName:Direct=OS:localhost\hangfire-{0}", "critical", "default");
app.UseHangfireServer();
Please use Hangfire Forum for long questions or questions with source code.