Publish message performance

I’ve a problem when using Messaging API:

When I using this code

public object Any(InventoryPrepare req)
    {
        var iMessageService = HostContext.TryResolve<IMessageService>();
        using (var mqClient = iMessageService.CreateMessageQueueClient())
        {
            mqClient.Publish(new KvMongoTrans
            {
                Key = req.Key,
                ConnectionString = req.ConnectionString,
                Advice = req.Advice,
                TrackingItem = req.TrackingItem,
                Status = BunchOfEnum.StatusTracking.Init
            });
        } return new EndBaseTracking(); }

The performance is really slow, 5000 msgs and 84 seconds
But it I change to

public object Any(InventoryPrepare req)
    {
	return new KvMongoTrans
        {
            Key = req.Key,
            ConnectionString = req.ConnectionString,
            Advice = req.Advice,
            TrackingItem = req.TrackingItem,
            Status = BunchOfEnum.StatusTracking.Init
        };
		}

It’s only 1 seconds for 5000 msg.
Can you explain with me this case ?
And in the first case, how can I improve this ? Because I want to publish message in 2 queues in this function

Thanks

In second case you don’t communicate with Rabbit Mq and process incoming messages directly on the web. In the first case the message is published to Rabbit Mq server and this is why returning from InventoryPrepare service takes more time.

Are you using .NET or .NET Core for tis solution? How do you measure execution speed, which tool you are using? And can you provide stand-alone sample which we can look into to see we can improve the number of processed messages.

Hi xplicit,

I’m using .NET Core. noOfThreads is 4
I think problem is connection to Rabbit.

using (var mqClient = iMessageService.CreateMessageQueueClient())
    {
        mqClient.Publish(new KvMongoTrans
        {
            Key = req.Key,
            ConnectionString = req.ConnectionString,
            Advice = req.Advice,
            TrackingItem = req.TrackingItem,
            Status = BunchOfEnum.StatusTracking.Init
        });
    }

When process this code, maybe CreateMessageQueueClient create a new connection, and my cpu is really high. I’ve read a reference link in here . I’ve resolved like that

var channel = SingletonChannelPool.Instance.OpenChannel();
        var producer = new RabbitProducer();
        try
        {
            producer.PublishMessageByExchange(channel, "mx.servicestack", "mq:KvMongoTrans.inq", new KvMongoTrans
            {
                Key = req.Key,
                ConnectionString = req.ConnectionString,
                Advice = req.Advice,
                TrackingItem = req.TrackingItem,
                Status = BunchOfEnum.StatusTracking.Init
            }.ToJson());
        }
        catch (System.Exception ex)
        {
            KvException.WriterException(ex, BunchOfEnum.KvExceptionType.RabbitMq);
        }
        SingletonChannelPool.Instance.CloseChannel(channel);

Using only 1 connection and open multi channels instead open a new connection. Can you tell me why ServiceStack RabbitMQ’s architecture not using 1 connection per process, and then use a channel per thread ?

Because it’s the standard way to handle resource connections amongst multiple providers agnostically where the optimal way for resource provider implementations to efficiently handle resource connections would be to instead transparently implement connection pooling behind-the-scenes not surface their bespoke connection handling and lifetime scope to all client implementations.

At the moment all MQ implementations use a shared API which we’re reluctant to change for an individual provider and will take time to implement and test, but in the meantime you can override how the Producer is created by overriding GetMessageProducer() in your AppHost.