ServiceStack.Redis:PooledRedisClientManager 和 RedisManagerPool 等待上一个请求完成
ServiceStack.Redis: PooledRedisClientManager and RedisManagerPool waits for prev req to finish
我正在测试作为 shown here, and reading the docs 的 Redis "full duplex" 通信,我认为 PooledRedisClientManager
和 RedisManagerPool
都有一个客户端池,因此能够并行处理多个 MQ 消息。
但是,在测试项目中,found here on Github,我好像不是这样的,或者是我漏掉了什么。解决方案包括:
- EventPublisher:用于将 Hello DTO 发布到 MQ 的 .NET Core WinForms 应用程序
- EventConsumer:具有用于处理 Hello DTO 的服务实现的 .NET Core WinFOrms 应用程序
我在 HelloService Any(Hello req)
中添加了一个 Thread.Sleep 并且当我从 EventPublisher 快速发送几个 Hello DTO 时,我希望它们在 EventConsumer 中同时处理,因为我认为池的客户将被使用。然而,这似乎并非如此。
HelloResponse
一个接一个地处理,似乎在同一个线程上。请看看这个短片:
这里,我向MQ连续发出了三个Hello DTO,在VS中的Outputwindow中,可以看到三个DTO是一个接一个处理的
我在 PooledRedisClientManager
和 RedisManagerPool
中都没有找到可以指定池大小的设置。
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.
这是一个没有上下文的无效结论。 Pooled Redis Client Managers 本身不执行任何操作,即它们只管理一个 redis 客户端池,这意味着当从池中检索客户端时:
var redis = clientsManager.GetClient();
RedisClient
(即单个 TCP 连接客户端到 redis 服务器)是从客户端管理器管理的客户端池中检索的,当客户端被释放时,它返回到池而不是 TCP正在终止连接。
这就是当某些东西使用池时可以假设的全部内容,客户端管理器不会自己执行 Redis 命令,并且应用程序使用它所做的事情是特定于它们的实现的。他们使用池的事实是无关紧要的,它们可以很容易地配置为在没有使用池的情况下使用 BasicRedisClientManager,即应用程序对客户端管理器的使用不会对它的使用方式做出任何假设.
在您的示例项目中,您正在使用 Redis MQ 来执行您的 ServiceStack 服务:
mqHost.RegisterHandler<Hello>(base.ExecuteMessage);
mqHost.Start(); //Starts listening for messages
在您的中您引用了:
Creates a Redis MQ Server that processes each message on its own background thread.
完整评论继续提供示例:
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)
这解释了 Redis MQ 服务器如何处理消息,即每个消息类型都在其自己的后台线程上处理,因此如果您阻塞消息工作线程,那么您将阻塞线程以阻塞该类型的其他消息(即请求数据传输协议)。
mqHost.RegisterHandler<Hello>(base.ExecuteMessage);
它不会阻止在自己的后台线程或优先级 MQ 线程上处理的其他消息,用于处理使用 Priority>0
发送的消息的类型。
Redis MQ 文档提供了一个示例,说明如何在注册处理程序时通过指定 noOfThreads
来增加用于处理每种消息类型的线程数:
轻松并行化和倍增您的服务吞吐量
RedisMqServer 还支持为单个请求生成任意数量的后台线程,因此如果发布到 twitter 是 IO 密集型操作,您可以通过简单地分配 2 个或更多工作线程来使吞吐量翻倍,例如:
mqService.RegisterHandler<PostStatusTwitter>(ExecuteMessage, noOfThreads:2);
mqService.RegisterHandler<CallFacebook>(ExecuteMessage);
mqService.RegisterHandler<EmailMessage>(ExecuteMessage);
我正在测试作为 shown here, and reading the docs 的 Redis "full duplex" 通信,我认为 PooledRedisClientManager
和 RedisManagerPool
都有一个客户端池,因此能够并行处理多个 MQ 消息。
但是,在测试项目中,found here on Github,我好像不是这样的,或者是我漏掉了什么。解决方案包括:
- EventPublisher:用于将 Hello DTO 发布到 MQ 的 .NET Core WinForms 应用程序
- EventConsumer:具有用于处理 Hello DTO 的服务实现的 .NET Core WinFOrms 应用程序
我在 HelloService Any(Hello req)
中添加了一个 Thread.Sleep 并且当我从 EventPublisher 快速发送几个 Hello DTO 时,我希望它们在 EventConsumer 中同时处理,因为我认为池的客户将被使用。然而,这似乎并非如此。
HelloResponse
一个接一个地处理,似乎在同一个线程上。请看看这个短片:
这里,我向MQ连续发出了三个Hello DTO,在VS中的Outputwindow中,可以看到三个DTO是一个接一个处理的
我在 PooledRedisClientManager
和 RedisManagerPool
中都没有找到可以指定池大小的设置。
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.
这是一个没有上下文的无效结论。 Pooled Redis Client Managers 本身不执行任何操作,即它们只管理一个 redis 客户端池,这意味着当从池中检索客户端时:
var redis = clientsManager.GetClient();
RedisClient
(即单个 TCP 连接客户端到 redis 服务器)是从客户端管理器管理的客户端池中检索的,当客户端被释放时,它返回到池而不是 TCP正在终止连接。
这就是当某些东西使用池时可以假设的全部内容,客户端管理器不会自己执行 Redis 命令,并且应用程序使用它所做的事情是特定于它们的实现的。他们使用池的事实是无关紧要的,它们可以很容易地配置为在没有使用池的情况下使用 BasicRedisClientManager,即应用程序对客户端管理器的使用不会对它的使用方式做出任何假设.
在您的示例项目中,您正在使用 Redis MQ 来执行您的 ServiceStack 服务:
mqHost.RegisterHandler<Hello>(base.ExecuteMessage);
mqHost.Start(); //Starts listening for messages
在您的
Creates a Redis MQ Server that processes each message on its own background thread.
完整评论继续提供示例:
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)
这解释了 Redis MQ 服务器如何处理消息,即每个消息类型都在其自己的后台线程上处理,因此如果您阻塞消息工作线程,那么您将阻塞线程以阻塞该类型的其他消息(即请求数据传输协议)。
mqHost.RegisterHandler<Hello>(base.ExecuteMessage);
它不会阻止在自己的后台线程或优先级 MQ 线程上处理的其他消息,用于处理使用 Priority>0
发送的消息的类型。
Redis MQ 文档提供了一个示例,说明如何在注册处理程序时通过指定 noOfThreads
来增加用于处理每种消息类型的线程数:
轻松并行化和倍增您的服务吞吐量
RedisMqServer 还支持为单个请求生成任意数量的后台线程,因此如果发布到 twitter 是 IO 密集型操作,您可以通过简单地分配 2 个或更多工作线程来使吞吐量翻倍,例如:
mqService.RegisterHandler<PostStatusTwitter>(ExecuteMessage, noOfThreads:2);
mqService.RegisterHandler<CallFacebook>(ExecuteMessage);
mqService.RegisterHandler<EmailMessage>(ExecuteMessage);