我可以在Redis中以一种订阅者模式订阅多台主机(和群集)吗?

时间:2019-03-21 15:02:04

标签: redis publish-subscribe

我正在实现一项功能,该功能将Redis发布的消息集成到我创建的项目并在测试环境中完美工作的mongodb中。

但是我关心的是生产环境,我有3个主服务器,它们存在12个从属群集。如果我将他们发布的消息发布到一种渠道模式,我可以将所有消息都订阅到一个地方

1 个答案:

答案 0 :(得分:1)

是的,通过stackexchange redis设置是可能的,我已经完成了如下所示的一般结构

 public class RedisSubscriber: IRedisSubscriber
    {
        private readonly RedisConfigurationManager _config;
        private readonly IMongoDbRepository _mongoDbRepository;
        private readonly ILogger<RedisSubscriber> _logger;
        private readonly IConnectionMultiplexer _connectionMultiplexer;


        public RedisSubscriber(IServiceProvider serviceLocator, ILogger<RedisSubscriber> logger, IConnectionMultiplexer conn)
        {
            _config = (RedisConfigurationManager)serviceLocator.GetService(typeof(RedisConfigurationManager));
            _mongoDbRepository = (IMongoDbRepository)serviceLocator.GetService(typeof(IMongoDbRepository));
            _connectionMultiplexer = conn;
            _logger = logger;
        }

        public void SubScribeChannel()
        {
            _logger.LogInformation("!SubScribeChannel started!!");

            string channelName = _config.ActiveChannelName;
            var pubSub = _connectionMultiplexer.GetSubscriber();
            try
            {
                pubSub.Subscribe(channelName, async (channel, message) => await MessageActionAsync(message, channel));
            }
            catch(Exception ex)
            {
                _logger.LogInformation(String.Format("!error: {0}", ex.Message));
            }
            Debug.WriteLine("EOF");
        }

        private async Task MessageActionAsync(RedisValue message, string channel)
        {
            try
            {
                Transformer t = new Transformer(_logger);
                _logger.LogInformation(String.Format("!SubScribeChannel message received on message!! channel: {0}, message: {1}", channel, message));
                string transformedMessage = Transformer.TransformJsonStringData2Message(message);
                List<Document> documents = Transformer.Deserialize<List<Document>>(transformedMessage);

                await MergeToMongoDb(documents, channel);
                _logger.LogInformation("!Merged");
            }
            catch (Exception ex)
            {
                _logger.LogInformation(String.Format("!error: {0}", ex.Message));
            }
        }

        private async Task MergeToMongoDb(IList<Document> documents, string channelName)
        {
            try
            {
                foreach (Document doc in documents)
                {
                    TurSysPartitionedDocument td = JsonConvert.DeserializeObject<TurSysPartitionedDocument>(JsonConvert.SerializeObject(doc));
                    td.DepartureDate = td.DepartureDate.ToLocalTime();
                    td.PartitionKey = channelName;
                    TurSysPartitionedDocument isExist = await _mongoDbRepository.GetOneAsync<TurSysPartitionedDocument>(k =>
                                k.ProductCode == td.ProductCode &&
                                k.ProviderCode == td.ProviderCode &&
                                k.CabinClassName == td.CabinClassName &&
                                k.OriginAirport == td.OriginAirport &&
                                k.DestinationAirport == td.DestinationAirport &&
                                k.Adult >= td.Adult &&
                                k.DepartureDate == td.DepartureDate,
                                td.PartitionKey);

                    if (isExist != null)
                    {
                        //_logger.LogInformation(String.Format("!isExist departure date: {0}", isExist.DepartureDate));
                        isExist.SearchCount++;
                        await _mongoDbRepository.UpdateOneAsync(isExist, k => k.Adult, td.Adult);
                        await _mongoDbRepository.UpdateOneAsync(isExist, k => k.SearchCount, isExist.SearchCount);
                    }
                    else
                    {
                        //_logger.LogInformation(String.Format("!last ToLocalTime td departure date: {0}", td.DepartureDate));
                        td.SearchCount = 1;
                        await _mongoDbRepository.AddOneAsync(td);
                        //_logger.LogInformation(String.Format("!last ToLocalTime result td departure date: {0}", td.DepartureDate));
                    }
                }
            }
            catch(Exception ex)
            {
                _logger.LogInformation(String.Format("!error: {0}", ex.Message));
            }
        }


    }