简体   繁体   English

Azure服务总线/服务结构消息未从队列中删除

[英]Azure Service Bus/Service Fabric message not being removed from queue

I am moving a calculation engine from an Azure worker role into Azure Service Fabric. 我正在将计算引擎从Azure辅助角色移动到Azure Service Fabric中。 It works by listening for messages on a Service Bus that it then processes based on the message content. 它的工作原理是监听服务总线上的消息,然后根据消息内容进行处理。

Currently, the calculation is working correctly but if the compute is taking longer than a minute or so the message does not get removed from the queue after completion. 目前,计算工作正常但如果计算花费的时间超过一分钟左右,则消息在完成后不会从队列中删除。 In the worker role, we solved this by increasing the "AutoRenewTimeout". 在worker角色中,我们通过增加“AutoRenewTimeout”来解决这个问题。

var options = new OnMessageOptions { AutoComplete = true, AutoRenewTimeout = TimeSpan.FromMinutes(3) };
        _queueClient.OnMessage(OnMessage, options);

However, using the "ServiceFabric.ServiceBus" nuget package, I cannot work out where you would set this. 但是,使用“ServiceFabric.ServiceBus” nuget包,我无法确定您设置它的位置。 I have used the demo project as a reference to set up a stateless service that actually runs the compute. 我已经使用演示项目作为参考来设置实际运行计算的无状态服务。 Below is an extract from CalculateService.cs where the Stateless Service is initialised. 以下是CalculateService.cs的摘录,其中初始化了无状态服务。

internal sealed class CalculateService : StatelessService
{
    public CalculateService(StatelessServiceContext context)
        : base(context)
    { }

    /// <summary>
    /// Optional override to create listeners (e.g., TCP, HTTP) for this service replica to handle client or user requests.
    /// </summary>
    /// <returns>A collection of listeners.</returns>
    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        string serviceBusQueueName = CloudConfigurationManager.GetSetting("QueueName");
        yield return new ServiceInstanceListener(context => new ServiceBusQueueCommunicationListener(new Handler(this), context, serviceBusQueueName), "StatelessService-ServiceBusQueueListener");
    }
}


internal sealed class Handler : AutoCompleteServiceBusMessageReceiver
{
    protected override Task ReceiveMessageImplAsync(BrokeredMessage message, CancellationToken cancellationToken)
    {
        ServiceEventSource.Current.ServiceMessage(_service, $"Handling queue message {message.MessageId}");
        var computeRole = new ExcelCompute();
        var rMessage = new RangeMessage();
        rMessage = message.GetBody<RangeMessage>();
        var result = computeRole.OnMessage(rMessage, message.MessageId); //returns true if the compute was successful (which it currently, always is)
        return Task.FromResult(result);
    }
 }

I did try using the <BrokeredMessage> message.Complete(); 我确实尝试使用<BrokeredMessage> message.Complete(); but that was throwing a message lock error. 但这是一个消息锁定错误。

  1. Get the latest version of the package (>= v3.5.0). 获取最新版本的软件包(> = v3.5.0)。 Set the property ' MessageLockRenewTimeSpan ' on your CommunicationListener to a value that is smaller than your lock duration. CommunicationListener上的属性“ MessageLockRenewTimeSpan ”设置为小于锁定持续时间的值。 (eg 50s where the lock duration is 60s) This allows for some clock skew. (例如,锁定持续时间为60秒的50秒)这允许一些时钟偏差。 Note: by default this property is null, which means no automatic lock renewal is done. 注意:默认情况下,此属性为null,这意味着不会执行自动锁定续订。

This option works well when processing a batch that takes more time than the lock duration allows. 处理批次所需的时间比锁定持续时间允许的时间长,此选项很有效。

or 要么

  1. You can use BrokeredMessage.RenewLock to periodically extend your message lock, when processing takes more time than the lock duration. 当处理花费的时间超过锁定持续时间时,您可以使用BrokeredMessage.RenewLock定期扩展消息锁定。 You could do that inside a separate thread if needed. 如果需要,您可以在单独的线程内执行此操作。 May be useful info 可能是有用的信息

This option works well when processing a single message (batch size 1) takes more time than the lock duration allows. 处理单个消息(批处理大小1)比锁定持续时间允许的时间更长时,此选项很有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM