【问题标题】:How can I publish to a ServiceStack.Redis Message Queue using StackExchange.Redis?如何使用 StackExchange.Redis 发布到 ServiceStack.Redis 消息队列?
【发布时间】:2020-07-05 09:48:48
【问题描述】:

我有现有的 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,以便我们可以对 Redis 进行异步调用,而 ServiceStack.Redis 不支持。

【问题讨论】:

    标签: c# redis stackexchange.redis servicestack.redis


    【解决方案1】:

    如果您想知道客户端发送了什么命令,您可以使用 redis-cli 中的 Redis 的 MONITOR debugging command,它可以让您实时查看发送到 redis-server 的所有命令。

    要模拟 Redis MQ 客户端,您还需要将队列名称发布到 Redis Pub/Sub 主题 QueueNames.TopicIn (mq:topic:in),它会通知 Redis MQ Server 消息已发布到该 MQ。

    【讨论】:

    • 这将是 QueueNames.TopicIn 的键,作为其中一个值为 MyRequest:in 的列表吗?我无法让监视器在我的机器上工作。
    • QueueNames.TopicIn 是静态字符串,值为“mq:topic:in”
    • 这更有意义,感谢您的链接。这会让我认为将 mq:MyRequest.inq 的值发布到 mq:topic:in 应该有效吗?到目前为止,我已经尝试过 mq:MyRequest.inq、mq:MyRequest、MyRequest.inq 和 MyRequest。他们现在都只是坐在那个列表中,实际请求本身也是如此
    • @Sorrien 向Redis Pub/Sub Topic 发布消息是暂时的,即它不会保留在列表中。我建议您运行 MONITOR,这样您就可以准确地看到正在发送的命令,它实际上只是 running a single redis-cli command
    • 我会试一试的。我认为这只是我使用的工具导致了我的问题。监视器只是没有向控制台写入任何内容。
    猜你喜欢
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    相关资源
    最近更新 更多