Как я могу опубликовать sh в очереди сообщений ServiceStack.Redis с помощью StackExchange.Redis? - PullRequest
0 голосов
/ 24 марта 2020

У меня есть сервисы ServiceStack, которые я хочу переключать на StackExchange.Redis по одному. Это предполагает обмен отправителями и, в конечном итоге, получателями. Этот вопрос касается публикации из StackExchange.Redis в ServiceStack.Redis.

Это простой издатель, который я собрал в консольном приложении для проверки концепции.

namespace SEMQSender
{
    public class MessagePublisher
    {
        IConnectionMultiplexer _connectionMultiplexer;
        public MessagePublisher()
        {
            _connectionMultiplexer = ConnectionMultiplexer.Connect(new ConfigurationOptions()
            {
                EndPoints = {
                        {
                        "MyRedisServer"
                        }
                },
                DefaultDatabase = 0,
                AllowAdmin = true,
                SyncTimeout = 100000
            });
        }

        public void Run()
        {
            var request = new MyRequest()
            {
                Id = 27
            };
            PushServiceStackRequest(request);
        }

        public void PushServiceStackRequest<T>(T request)
        {
            var messageText = SerializeRequestAsServiceStackMessage(request);
            Push($"mq:{request.GetType().Name}.inq", messageText);
        }

        public string SerializeRequestAsServiceStackMessage<T>(T request)
        {
            var requestJson = JsonSerializer.Serialize(request);
            requestJson.Remove(0, 1);
            var serviceStackMessage = new ServiceStackMessage()
            {
                Id = Guid.NewGuid(),
                CreatedDate = DateTimeOffset.Now,
                Options = 1,
                Priority = 0,
                RetryAttempts = 0
            };
            var messageJson = JsonSerializer.Serialize(serviceStackMessage);
            var requestType = request.GetType();
            var sBuilder = new StringBuilder();
            sBuilder.AppendJoin('.', requestType.Namespace.Split('.').Take(2));
            var ns = sBuilder.ToString();
            var result = $"{messageJson.Remove(messageJson.Length - 1, 1)}, \"Body\":{{\"__type\":\"{requestType.FullName}, {ns}\",{requestJson.Remove(0, 1)}}}";
            return result;
        }

        public void Push(RedisKey queueName, RedisValue value)
        {
            _connectionMultiplexer.GetDatabase().ListRightPush(queueName, value);
        }
    }

    public class ServiceStackRedisMessage
    {
        public Guid Id { get; set; }
        public DateTimeOffset CreatedDate { get; set; }
        public int Priority { get; set; }
        public int RetryAttempts { get; set; }
        public int Options { get; set; }
    }
}

namespace MyServiceStackService.ServiceModel.MyService
{
    public class MyRequest
    {
        public int Id { get; set; }
    }
}

, и это пример того, как наши сервисы ServiceStack подписываются на сообщения redis

    container.Register<IRedisClientsManager>(c => new RedisManagerPool(ConfigurationManager.AppSettings["Redis"]));
    container.Register<ICacheClient>(c => container.Resolve<IRedisClientsManager>().GetCacheClient());
    var mqHost = new RedisMqServer(container.Resolve<IRedisClientsManager>(), retryCount: 2);
    container.Register<IMessageService>(c => mqHost);

    mqHost.RegisterHandler<MyRequest>(this.ServiceController.ExecuteMessage);

    mqHost.Start();

Насколько я могу судить, ключ и значение Redis идентичны тому, что я сгенерировал бы, если бы я опубликовал сообщение с использованием ServiceStack, но что-то странное происходит на стороне абонента. Сообщения забираются из очереди только при первом запуске службы. Все сообщения, помещенные в очередь после этого, остаются там, где они есть, до перезапуска службы. Полученные сообщения содержат все ожидаемые данные об десериализованном объекте.

Надеемся, что кто-то с большим знанием StackExchange.Redis или ServiceStack.Redis может помочь с этим. На всякий случай, если кому-то интересно: мы переключаемся на StackExchange.Redis, чтобы мы могли совершать асинхронные c вызовы Redis, которые ServiceStack.Redis не поддерживает.

1 Ответ

1 голос
/ 25 марта 2020

Если вы хотите узнать, какие команды отправляет клиент, вы можете использовать команду отладки MONITOR Redis из redis-cli, которая позволит вам видеть все команды, отправленные на сервер redis в режиме реального времени.

Для имитации c клиента Redis MQ вам также необходимо опубликовать sh имя очереди в Redis Pub / Sub Topi c QueueNames.TopicIn (mq:topic:in), которая уведомляет Redis MQ Server , что сообщения были опубликованы на этом MQ.

...