ServiceStack.Redis: PooledRedisClientManager и RedisManagerPool ожидает завершения предыдущего запроса - PullRequest
0 голосов
/ 04 мая 2020

Я тестирую связь Redis "full duplex" как , показанную здесь , и читаю документы , я думал, что PooledRedisClientManager, а также RedisManagerPool имеют пул клиентов и, следовательно, возможность обрабатывать несколько сообщений MQ параллельно.

Однако в тестовом проекте , найденном здесь на Github , мне кажется, что это не так или я что-то упустил. Решение состоит из:

  • EventPublisher:. NET Базовое приложение WinForms для публикации Hello DTO в MQ
  • EventConsumer:. NET Базовое приложение WinFOrms, которое имеет Service Impl для обработка Hello DTO

Я добавил Thread.Sleep внутри HelloService Any(Hello req), и когда я из EventPublisher отправил несколько Hello DTO быстро, я ожидал, что они будут обрабатываться одновременно в EventConsumer, так как я думал, что пул клиентов будет использоваться. Это, однако, похоже, не соответствует действительности.

HelloResponse обрабатываются один за другим, в том же потоке, как кажется. Пожалуйста, взгляните на это короткое видео:

http://somup.com/cYheY8iNml

Здесь я быстро запускаю три Hello DTO для MQ и в окне Output. в VS вы можете видеть, что три DTO обрабатываются один за другим.

Я не нашел настройки в PooledRedisClientManager или RedisManagerPool, где я мог бы указать размер пула.

1 Ответ

0 голосов
/ 04 мая 2020

Я думал, что PooledRedisClientManager, а также RedisManagerPool имеют пул клиентов

Это утверждение верно.

и, таким образом, может обрабатывать несколько Сообщения MQ параллельно.

Это неверный вывод, который не имеет смысла без контекста. Пул Менеджеры Redis Client сами не выполняют никаких действий, т.е. они управляют только пулом клиентов Redis, то есть когда клиент извлекается из пула:

var redis = clientsManager.GetClient();

RedisClient (т. е. один клиент, подключенный по протоколу TCP к серверу Redis) был извлечен из пула клиентов, управляемых менеджером клиентов, и что при удалении клиента он возвращается в пул, а не прерывается соединение TCP.

Это все, что можно предположить, когда кто-то использует пул, менеджеры клиентов не выполняют команды Redis сами по себе, и то, что делает приложение, которое их использует, указывает c на их реализацию. Тот факт, что они используют пул, не имеет значения, их можно легко настроить на использование BasicRedisClientManager , где пул не используется, т.е. использование приложением менеджера клиентов не делает никаких предположений о том, как оно

В вашем примере проекта вы используете Redis MQ для выполнения ваших ServiceStack Services:

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

В вашем предыдущем ответе Вы цитируете:

Создает сервер Redis MQ, который обрабатывает каждое сообщение в своем фоновом потоке.

Полный комментарий приведен в качестве примера:

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 Server обрабатывает сообщения, т.е. каждый тип сообщения обрабатывается в своем собственном фоновом потоке, поэтому, если вы блокируете рабочий поток сообщений, то вы блокируете поток для блокировки других сообщений для этого типа ( т.е. запрос DTO).

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

Он не блокирует другие сообщения, которые обрабатываются в их собственном фоновом потоке или в потоке Priority MQ для этого типа, обрабатывая сообщения, отправленные с Priority>0.

Redis MQ docs предоставляет пример того, как вы можете увеличить количество потоков, используемых для обработки каждого типа сообщений, указав noOfThreads при регистрации обработчика:

Простое распараллеливание и умножение пропускной способности ваших служб

RedisMqServer также поддерживает создание любого количества фоновых потоков для отдельных запросов, поэтому, если публикация в твиттере была интенсивной операцией ввода-вывода, вы можете удвоить пропускную способность, просто назначив 2 или более рабочих потоков, например:

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