RabbitMq停止接收消息.Net Core

时间:2018-05-16 06:45:09

标签: c# docker rabbitmq .net-core

我在 .Net Core 上开发的服务很少,我使用 RabbitMq 在服务之间发送消息。为了接收消息,我构建了从IHostedService继承的服务,这些服务连接到RabbitMq并使用。您可以在下面找到我的基本信息接收器

public abstract class MessageReceiver<TMessage> : IMessageReceiver<TMessage>
{
    private readonly IServiceScopeFactory _scopeFactory;        

    private Task _executingTask;

    private CancellationTokenSource _cts;

    public string QueueName { get; private set; }

    private readonly IMessageHandler<TMessage> _handler;

    public MessageReceiver(IServiceScopeFactory scopeFactory, IMessageHandler<TMessage> handler, string queueName)
    {
        _scopeFactory = scopeFactory;
        QueueName = queueName;
        _handler = handler;
    }

    public virtual async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var factory = scope.ServiceProvider.GetRequiredService<IConnectionFactory>();
            var connection = factory.CreateConnection();
            var connectionModel = connection.CreateModel();
            connectionModel.QueueDeclare(QueueName, true, false, false, null);
            connectionModel.BasicQos(0, 100, false);
            var basicProperties = connectionModel.CreateBasicProperties();
            basicProperties.Persistent = true;

            while (!cancellationToken.IsCancellationRequested)
            {
                var consumer = new EventingBasicConsumer(connectionModel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    _handler.Handle(body);
                };

                connectionModel.BasicConsume(QueueName, autoAck: true, consumer: consumer);
                await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
            }
        }
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
        _executingTask = ExecuteAsync(_cts.Token);
        return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        if (_executingTask == null)
        {
            return;
        }

        _cts.Cancel();
        await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
        cancellationToken.ThrowIfCancellationRequested();
    }

正如你可以看到它的泛型,所以我也建立IMessageHandler实际上已经实现了我们的业务逻辑 - 处理收到的消息

这是消息接收者之一

public class DemoReceiver : MessageReceiver<DemoMessage>
{        
    public DemoReceiver (IServiceScopeFactory factory, IMessageHandler<DemoMessage> handler) : base(factory, handler, QueueNames.Demo)
    {
    }
}

更重要的一点 - 应用程序正在 Docker 上运行。所以问题是 - 我只是注意到有时它的stoppes消耗来自队列的消息。所以我在RabbitMq队列仪表板中看到了待处理的消息。我不知道是什么原因导致了这个问题。也许它的IHostedService只是'睡觉'而且不会跑。你有什么想法吗?

0 个答案:

没有答案