我有一个服务,需要在startup
处连接到另一个服务。另一个服务是Rabbitmq
经纪人。
我正在监听Rabbitmq
中的某个事件,因此我需要从应用程序的开始处将其激活。
我需要连接到两个不同的VHost
,所以我需要创建两个连接。
问题是,当我启动应用程序时,它会不断创建连接,直到服务器崩溃!
在Rabbitmq管理中,我可以看到创建了很多Connection
和Channels
。
我不知道为什么会这样。
通常,我想知道在dotnet core中启动应用程序时,连接到其他服务的正确方法是什么。
我正在使用此代码执行此操作:
public void ConfigureServices(IServiceCollection services)
{
.....
services.AddSingleton<RabbitConnectionService>();
...
ActivatorUtilities.CreateInstance<RabbitConnectionService>(services.BuildServiceProvider());
}
并且在RabbitConnectionService
的构造函数中,我正在连接到Rabbitmq
。
public RabbitConnectionService(IConfiguration configuration)
{
ServersMessageQueue = new MessageQueue(configuration.GetConnectionString("FirstVhost"), "First");
ClientsMessageQueue = new MessageQueue(configuration.GetConnectionString("SecondVhost"), "Second");
}
MessageQueue类:
public class MessageQueue
{
private IConnection connection;
private string RabbitURI;
private string ConnectionName;
static Logger _logger = LogManager.GetCurrentClassLogger();
public MessageQueue(string connectionUri, string connectionName)
{
ConnectionName = connectionName;
RabbitURI = connectionUri;
connection = CreateConnection();
}
private IConnection CreateConnection()
{
ConnectionFactory factory = new ConnectionFactory();
factory.Uri = new Uri(RabbitURI);
factory.AutomaticRecoveryEnabled = true;
factory.RequestedHeartbeat = 10;
return factory.CreateConnection(ConnectionName);
}
public IModel CreateChannel()
{
return connection.CreateModel();
}
...
}
要启用后台处理,您需要创建一个实现IHostedService
接口的类。
public interface IHostedService
{
Task StartAsync(CancellationToken cancellationToken);
Task StopAsync(CancellationToken cancellationToken);
}
此接口有两种方法StartAsync
和StopAsync
。并且您需要使用依赖注入来注册服务,如下所示:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<IHostedService, DemoService>();
...
}
代替实现IHostedService
,可以从BackgroundService
抽象类派生,并且可以实现ExecuteAsync
抽象方法。这是最小后台服务的示例,该后台服务监视SQL Server中的表并发送电子邮件:
public class DemoService : BackgroundService
{
private readonly ILogger<DemoService> _demoservicelogger;
private readonly DemoContext _demoContext;
private readonly IEmailService _emailService;
public DemoService(ILogger<DemoService> demoservicelogger,
DemoContext demoContext, IEmailService emailService)
{
_demoservicelogger = demoservicelogger;
_demoContext = demoContext;
_emailService = emailService;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_demoservicelogger.LogDebug("Demo Service is starting");
stoppingToken.Register(() => _demoservicelogger.LogDebug("Demo Service is stopping."));
while (!stoppingToken.IsCancellationRequested)
{
_demoservicelogger.LogDebug("Demo Service is running in background");
var pendingEmailTasks = _demoContext.EmailTasks
.Where(x => !x.IsEmailSent).AsEnumerable();
await SendEmailsAsync(pendingEmailTasks);
await Task.Delay(1000 * 60 * 5, stoppingToken);
}
_demoservicelogger.LogDebug("Demo service is stopping");
}
}
感谢伊恩·坎普。