Skip to content

Unable to deserialize the body bytes into object after upgrade the RabbitMQ Client from 5.1.1 to 6.2.4 #1167

@LoremipsumSharp

Description

@LoremipsumSharp

I am using RabbitMQ.Client for messaging and using dead letter pattern to implement retry mechanism, everything works fine with RabbitMQ.Client with version :5.1.1 .

The pseudo-code is below:

public async Task Handle(BasicDeliverEventArgs basicDeliverEventArgs)
{

    try
    {
        var bodyBytes = basicDeliverEventArgs.Body.ToArray();
        var bodyString = Encoding.UTF8.GetString(bodyBytes);
        // extension method with newtonsoft.json behind
        bodyString.TryDeserializeObject<T>(out var message);
        // do somesting
    }
    catch (Exception ex)
    {
        var properties = basicDeliverEventArgs.BasicProperties;
        if (properties.Headers == null)
        {
            properties.Headers = new Dictionary<string, object>();
        }

        var bodyBytes = basicDeliverEventArgs.Body.ToArray();


        var bodyString = Encoding.UTF8.GetString(bodyBytes);

        // retrive the x-death-count by header 
        var retryTimes = GetRetryTimes(properties.Headers);

        if (retryTimes <= _retryConfiguration.MaxCount)
        {
            using var channel = _conn.CreateModel();
            var delay = _retryConfiguration.GetNextDelay(retryTimes);
            properties.Expiration = delay.TotalMilliseconds.ToString();
            string deadLetterExchangeName = $"ErrorExchange_{_rabbitSubscriptionConfiguration.Queue}";
            string deadLetterQueueName = $"{_rabbitSubscriptionConfiguration.Queue}.Deadletter";
            string deadLetterRoutingKey = $"{_rabbitSubscriptionConfiguration.RoutingKey}.Deadletter";

            channel.ExchangeDeclare(deadLetterExchangeName, "direct", true, true);
            channel.QueueDeclare(deadLetterQueueName, true, false, false, new Dictionary<string, object>()
            {
                { "x-dead-letter-exchange", deadLetterExchangeName },
                { "x-dead-letter-routing-key",_rabbitSubscriptionConfiguration.RoutingKey}
            });

            channel.QueueBind(_rabbitSubscriptionConfiguration.Queue, deadLetterExchangeName, _rabbitSubscriptionConfiguration.RoutingKey);
            channel.QueueBind(deadLetterQueueName, deadLetterExchangeName, deadLetterRoutingKey);

            channel.BasicPublish(deadLetterExchangeName, deadLetterRoutingKey, false, properties, bodyBytes);
        }
        else
        {
            var messageStorage = _serviceProvider.GetService<IMessageStorage>();
            await messageStorage.StoreDeadLetter(bodyString, ex);
        }
    }
}
        

However, when I upgrade the RabbitMQ.Client to 6.2.4,there is some probability that the body bytes of message unable deserialize to origin object when I receiving the message again from dead letter queue.

When the retry ended,I inspect the dead letter in the database,some of them failed to convert to a normal string

By the way,the version of RabbitMQ Server is 3.8.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions