ServiceStack.Redis: PooledRedisClientManager and RedisManagerPool waits for prev req to finish

北慕城南 提交于 2020-05-17 07:10:07

问题


I am testing out the Redis "full duplex" communication as shown here, and reading the docs, I thought that the PooledRedisClientManager as well as RedisManagerPool have a pool of clients, and thus being able to process several MQ messages in parallel.

However, in the test project, found here on Github, it seems to me that this is not the case, or I am missing something. The solution consists of:

  • EventPublisher: .NET Core WinForms application for publishing Hello DTOs to the MQ
  • EventConsumer: .NET Core WinFOrms application that has Service impl for handling Hello DTOs

I added a Thread.Sleep inside the HelloService Any(Hello req) and when I from the EventPublisher send several Hello DTOs quickly, I was expecting them to be handled concurrently in the EventConsumer, as I thought the pool of clients would be used. This, however, doesnt seem to be the case.

The HelloResponses are handled one after the other, on the same thread it seems. Please take a look at this short video:

http://somup.com/cYheY8iNml

Here, I fire off three Hello DTOs to the MQ in quick succession, and in the Output window in VS, you can see that the three DTOs are handled one after each other.

I did not find a setting in PooledRedisClientManager nor RedisManagerPool where I could specify the pool size.


回答1:


I thought that the PooledRedisClientManager as well as RedisManagerPool have a pool of clients

This statement is true.

and thus being able to process several MQ messages in parallel.

This is an invalid conclusion that's meaningless without context. The Pooled Redis Client Managers do not do any execution themselves, i.e. they only manage a pool of redis clients meaning when a client is retrieved from the pool:

var redis = clientsManager.GetClient();

The RedisClient (i.e. single TCP connected client to redis server) was retrieved from a pool of clients managed by the client manager and that when the client is disposed, it's returned to the pool instead of the TCP connection being terminated.

That's all that can be assumed when something is using a pool, the Client Managers don't execute Redis commands by themselves, and what the application does that uses it is specific to their implementation. The fact that they're using a pool is irrelevant, they could easily be configured to use the BasicRedisClientManager where no pool is used, i.e. an Application's use of a client manager doesn't make any assumption of how it's being used.

In your example project you're using Redis MQ to execute your ServiceStack Services:

mqHost.RegisterHandler<Hello>(base.ExecuteMessage);
mqHost.Start(); //Starts listening for messages

In your previous answer you've quoted:

Creates a Redis MQ Server that processes each message on its own background thread.

The full comment goes on to provide an example:

i.e. if you register 3 handlers it will create 7 background threads:
///   - 1 listening to the Redis MQ Subscription, getting notified of each new message
///   - 3x1 Normal InQ for each message handler
///   - 3x1 PriorityQ for each message handler (Turn off with DisablePriorityQueues)

Which explains how Redis MQ Server processes messages, i.e. each message Type is processed on its own background Thread, so if you block the message worker thread then you're blocking thread for blocking other messages for that Type (i.e. Request DTO).

mqHost.RegisterHandler<Hello>(base.ExecuteMessage);

It doesn't block other messages which are processed on their own background thread or the Priority MQ thread for that Type processing messages sent with Priority>0.

The Redis MQ docs provides an example of how you can increase the number of threads used to process each message type by specifying the noOfThreads when registering the handler:

Easily Parallelize and Multiply your services throughput

The RedisMqServer also supports spawning any number of background threads for individual requests, so if Posting to twitter was an IO intensive operation you can double the throughput by simply assigning 2 or more worker threads, e.g:

mqService.RegisterHandler<PostStatusTwitter>(ExecuteMessage, noOfThreads:2);
mqService.RegisterHandler<CallFacebook>(ExecuteMessage);
mqService.RegisterHandler<EmailMessage>(ExecuteMessage);


来源:https://stackoverflow.com/questions/61581570/servicestack-redis-pooledredisclientmanager-and-redismanagerpool-waits-for-prev

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!