private void NetSubscribe(Action <string, string> action, string mqpath, string channel)
 {
     while (!cancelSource.IsCancellationRequested)
     {
         try
         {
             try
             {
                 CloseRedisClient();
                 RedisSubscribe(action, mqpath, channel);
             }
             catch (Exception exp)
             {
                 if (isdisposeing == false)
                 {
                     ErrorLogHelper.WriteLine(-1, mqpath, "NetSubscribe", string.Format("MQ心跳redis订阅通信消息出错,请检查redis服务器,订阅名:{0}", Name), exp);
                 }
             }
             System.Threading.Thread.Sleep(SystemParamConfig.Redis_Subscribe_FailConnect_ReConnect_Every_Time * 1000);
         }
         catch (Exception exp)
         {
             // when thread is sleeping,but we cancel this thread,may throw thread abort error
         }
     }
 }
示例#2
0
        public void Open()
        {
            try
            {
                DebugHelper.WriteLine(-1, MQPath, "Open", "生产者开始初始化");
                //初始化上下文信息
                ProducterBLL bll = new ProducterBLL();
                SqlHelper.ExcuteSql(Config.ManageConnectString, (c) =>
                {
                    Context.ProducterInfo             = bll.GetProducterInfo(c, MQPath, ProducterName);
                    Context.ProducterInfo.LoadBalance = LoadBalance;
                    Context.ManageServerTime          = c.GetServerDate();
                });
                Context.IsNeedReload         = false;
                Context.LastMQPathUpdateTime = Context.ProducterInfo.MqPathModel.lastupdatetime;

                //获取系统配置信息
                ConfigHelper.LoadConfig(Config.ManageConnectString);

                NetCommand = new RedisNetCommand(ConfigHelper.RedisServer);
                ProducterHeartbeatProtect.Instance(Context).Contexts.Add(Context);//注册上下文
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Open", "生产者初始化成功");
                LogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Open", "生产者初始化成功");
            }
            catch (Exception exp)
            {
                ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Open", "生产者初始化", exp);
                throw exp;
            }
        }
 private void HeatbeatRun()
 {
     while (!cancelSource.IsCancellationRequested)
     {
         try
         {
             foreach (var context in Contexts.CopyToList())
             {
                 ProducterBLL bll = new ProducterBLL();
                 SqlHelper.ExcuteSql(context.ProducterProvider.Config.ManageConnectString, (c) =>
                 {
                     context.ManageServerTime = c.GetServerDate();//重新校准时间
                     bll.ProducterHeartbeat(c, context.ProducterInfo.ProducterModel.tempid, context.ProducterInfo.ProducterModel.mqpathid);
                 });
                 CheckMqPathUpdate(context);
             }
         }
         catch (Exception exp)
         {
             ErrorLogHelper.WriteLine(-1, "", "HeatbeatRun", "生产者心跳循环错误", exp);
         }
         System.Threading.Thread.Sleep(SystemParamConfig.Producter_HeatBeat_Every_Time * 1000);
         DebugHelper.WriteLine(-1, "", "HeatbeatRun", "生产者心跳循环一轮结束");
     }
 }
 private void RedisListenerCommand(string channel, string msg)
 {
     if (Contexts.Count == 0)
     {
         return;
     }
     try
     {
         DebugHelper.WriteLine(-1, "", "RedisListenerCommand", "生产者心跳接收到redis消息开始处理");
         foreach (var context in Contexts.CopyToList())
         {
             var command = new XXF.Serialization.JsonHelper().Deserialize <BusinessMQNetCommand>(msg);
             if ((command.CommandReceiver == EnumCommandReceiver.All || command.CommandReceiver == EnumCommandReceiver.Producter) && command.MqPath.ToLower() == context.ProducterProvider.MQPath.ToLower())
             {
                 if (command.CommandType == EnumCommandType.Register)
                 {
                     context.IsNeedReload = true;
                     CheckMqPathUpdate(context);
                 }
             }
         }
         DebugHelper.WriteLine(-1, "", "RedisListenerCommand", "生产者心跳接收到redis消息处理完毕");
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(-1, "", "RedisListenerCommand", "生产者Redis命令监听出错", exp);
     }
 }
示例#5
0
        /// <summary>
        /// 资源释放
        /// </summary>
        public void Dispose()
        {
            try
            {
                ProducterBLL bll = new ProducterBLL();
                SqlHelper.ExcuteSql(Config.ManageConnectString, (c) =>
                {
                    bll.RemoveProducter(c, Context.ProducterInfo.ProducterModel.tempid, Context.ProducterInfo.MqPathModel.id);
                });
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "生产者移除注册信息成功");
                LogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "生产者移除注册信息成功");
            }
            catch (Exception exp)
            {
                ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "生产者移除注册信息出错", exp);
            }

            try
            {
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "生产者资源开始释放");
                ProducterHeartbeatProtect.Instance(Context).Contexts.Remove(Context); //移除上下文
                Context.Dispose();                                                    //释放上下文

                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "生产者资源释放成功");
                LogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "生产者资源释放成功");
            }
            catch (Exception exp)
            {
                ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "生产者资源释放出错", exp);
                throw exp;
            }
        }
示例#6
0
        public ConsumerHeartbeatProtect(ConsumerContext context)
        {
            try
            {
                Context = context;
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect", "消费者准备心跳注册");

                _lastupdatetimeofmqpath = GetLastUpdateTimeOfMqPath();
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect", "消费者获取队列最后更新时间成功");

                cancelSource = new CancellationTokenSource();
                System.Threading.Tasks.Task.Factory.StartNew(() =>
                {
                    HeartBeatRun();//开启心跳检查
                }, cancelSource.Token);
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect", "消费者开启心跳循环成功");

                redislistener = new RedisNetCommandListener(ConfigHelper.RedisServer); redislistener.Name = "消费者" + context.ConsumerProvider.Client;
                redislistener.Register((channel, msg) =>
                {
                    RedisListenerCommand(channel, msg);
                }, cancelSource, Context.ConsumerProvider.MQPath, SystemParamConfig.Redis_Channel);
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect", "消费者开启Redis消息订阅成功");
                LogHelper.WriteLine(Context.ConsumerInfo.MQPathModel.id, Context.ConsumerInfo.MQPathModel.mqpath, "ConsumerHeartbeatProtect", "消费者心跳注册成功");
            }
            catch (Exception exp)
            {
                ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect", "消费者心跳守护初始化", exp);
                throw exp;
            }
        }
示例#7
0
 /// <summary>
 /// 加载配置
 /// </summary>
 /// <param name="manageconnectstring"></param>
 public static void LoadConfig(string manageconnectstring)
 {
     try
     {
         List <tb_config_model> configs = new List <tb_config_model>();
         SqlHelper.ExcuteSql(manageconnectstring, (c) => { configs = new DB.ConsumerBLL().GetConfig(c); });
         foreach (var c in configs)
         {
             if (c.key.ToLower() == EnumSystemConfigKey.RedisServer.ToString().ToLower())
             {
                 RedisServer = c.value;
             }
             else if (c.key.ToLower() == EnumSystemConfigKey.DebugMqpath.ToString().ToLower())
             {
                 DebugMqpath = c.value;
             }
             else if (c.key.ToLower() == EnumSystemConfigKey.LogDBConnectString.ToString().ToLower())
             {
                 LogDBConnectString = c.value;
             }
         }
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(-1, "", "LoadConfig", "初始化系统配置表信息出错", exp);
     }
 }
        private ProducterHeartbeatProtect(ProducterContext context)
        {
            try
            {
                DebugHelper.WriteLine(context.GetMQPathID(), context.GetMQPath(), "ProducterHeartbeatProtect", "生产者心跳守护开始注册");
                cancelSource = new CancellationTokenSource();

                System.Threading.Tasks.Task.Factory.StartNew(() =>
                {
                    HeatbeatRun();//注册心跳
                }, cancelSource.Token);
                DebugHelper.WriteLine(context.GetMQPathID(), context.GetMQPath(), "ProducterHeartbeatProtect", "生产者心跳守护心跳注册成功");

                redislistener = new RedisNetCommandListener(ConfigHelper.RedisServer); redislistener.Name = "生产者";
                redislistener.Register((channel, msg) =>
                {
                    RedisListenerCommand(channel, msg);
                }, cancelSource, context.ProducterProvider.MQPath, SystemParamConfig.Redis_Channel);
                DebugHelper.WriteLine(context.GetMQPathID(), context.GetMQPath(), "ProducterHeartbeatProtect", "生产者心跳redis监听注册成功");
                LogHelper.WriteLine(context.GetMQPathID(), context.GetMQPath(), "ProducterHeartbeatProtect", "生产者心跳守护注册成功");
            }
            catch (Exception exp)
            {
                ErrorLogHelper.WriteLine(context.GetMQPathID(), context.GetMQPath(), "ProducterHeartbeatProtect", "生产者心跳初始化错误", exp);
                throw exp;
            }
        }
示例#9
0
        private void Create()
        {
            try
            {
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-Create", "消费者开始创建内部消息队列");
                Init();
                cancelSource = new CancellationTokenSource();

                System.Threading.Tasks.Task.Factory.StartNew(() =>
                {
                    Run();
                }, cancelSource.Token);
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-Create", "消费者内部消息队列注册消息循环成功");

                redislistener = new RedisNetCommandListener(ConfigHelper.RedisServer); redislistener.Name = "消费者内部消息队列";
                redislistener.Register((channel, msg) =>
                {
                    RedisListenerCommand(channel, msg);
                }, cancelSource, Context.ConsumerProvider.MQPath, SystemParamConfig.Redis_Channel_Quque + "." + Context.ConsumerProvider.MQPath);
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-Create", "消费者内部消息队列注册redis消息监听成功");

                LogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-Create", "消费者内部队列注册成功");
            }
            catch (Exception exp)
            {
                ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-Create", "消费者内部消息队列创建失败", exp);
                throw exp;
            }
        }
示例#10
0
 //心跳循环
 private void HeartBeatRun()
 {
     try
     {
         while (!cancelSource.IsCancellationRequested)
         {
             HeartBeatTask();
             System.Threading.Thread.Sleep(SystemParamConfig.Consumer_HeatBeat_Every_Time * 1000);
             DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect-HeartBeatRun", "心跳循环一轮完毕");
         }
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(Context.ConsumerInfo.MQPathModel.id, Context.ConsumerInfo.MQPathModel.mqpath, "HeartBeatRun", "消费者心跳循环方法", exp);
     }
 }
 static void CurrentDomain_DomainUnload(object sender, EventArgs e)
 {
     try
     {
         if (_singleton != null)
         {
             _singleton.Dispose();
         }
         LogHelper.WriteLine(-1, "", "CurrentDomain_DomainUnload", "当前域域卸载时释放生产者完毕");
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(-1, "", "CurrentDomain_DomainUnload", "当前域域卸载释放生产者连接池出错", exp);
         throw exp;
     }
 }
示例#12
0
 private void RedisListenerCommand(string channel, string msg)
 {
     try
     {
         if (!cancelSource.IsCancellationRequested)
         {
             messagelock.Lock(() =>
             {
                 DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-RedisListenerCommand", "消费者Redis开始执行消息命令");
                 this.TiggerMessagesTask();
                 DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-RedisListenerCommand", "消费者Redis消息命令执行完毕");
             });
         }
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-RedisListenerCommand", "消费者Redis监听消息命令", exp);
     }
 }
 public void Dispose()
 {
     if (Context != null)
     {
         try
         {
             DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "开始消费者资源释放");
             if (Context != null)
             {
                 Context.Dispose();
             }
             DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "消费者上下文资源释放成功");
         }
         catch (Exception exp)
         {
             ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "消费者资源释放出错", exp);
             throw new BusinessMQException("释放订阅客户端消息处理资源失败", exp);
         }
         finally
         {
             try
             {
                 ConsumerBLL bll = new ConsumerBLL();
                 //取消注册
                 SqlHelper.ExcuteSql(Config.ManageConnectString, (c) =>
                 {
                     bll.RemoveConsumer(c, Context.ConsumerInfo.ConsumerModel.tempid, Context.ConsumerInfo.ConsumerModel.consumerclientid);
                 });
                 DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "消费者注销注册信息成功");
                 LogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "消费者资源释放成功");
             }
             catch (Exception exp1)
             {
                 ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "Dispose", "消费者资源释放出错", exp1);
                 throw new BusinessMQException("移除订阅客户端注册信息失败", exp1);
             }
             finally
             {
                 Context = null;
             }
         }
     }
 }
示例#14
0
 private void SendMessagesToConsume()
 {
     Parallel.ForEach(Context.ConsumerInfo.ConsumerPartitionModels, new ParallelOptions()
     {
         CancellationToken = cancelSource.Token, MaxDegreeOfParallelism = Context.ConsumerProvider.MaxReceiveMQThread
     }, (partition) =>
     {
         //Context.ConsumerInfo.ConsumerPartitionModels.ForEach((partition) =>
         //{
         var m = Queue.Dequeue(partition.partitionid);
         while (m != null)
         {
             if (cancelSource.IsCancellationRequested)
             {
                 return;
             }
             try
             {
                 Context.ActionInfo.InnerAction(m);
                 if (m.IsMarkFinished == false)
                 {
                     throw new BusinessMQException(string.Format("当前消息未标记为已消费状态,json:{0},id:{1}", m.Model.message, m.Model.id));//抛出错误且该分区的消息处理将停滞。
                 }
                 else
                 {
                     m = Queue.Dequeue(partition.partitionid);
                 }
             }
             catch (Exception exp)
             {
                 string msg = string.Format("MQ消息处理出错,json:{0},id:{1}", m.Model.message, m.Model.id);
                 if (!errorpartitions.ContainsKey(partition.partitionid))
                 {
                     errorpartitions.Add(partition.partitionid, new BusinessMQException(msg, exp));
                 }
                 ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-SendMessagesToConsume", msg, exp);
                 return;
             }
         }
     });
 }
        private void RedisSubscribe(Action <string, string> action, string mqpath, string channelname)
        {
            var manager = new XXF.Redis.RedisManager();

            redisDb = manager.CreateClient(RedisServerIp.Split(':')[0], Convert.ToInt32(RedisServerIp.Split(':')[1]), "");
            using (var subscription = redisDb.GetClient().CreateSubscription())
            {
                subscription.OnSubscribe = channel =>
                {
                    //订阅事件
                };
                subscription.OnUnSubscribe = channel =>
                {
                    //退订事件
                };
                subscription.OnMessage = (channel, msg) =>
                {
                    try
                    {
                        if (msg == "RedisNetCommandListener-Close" || isdisposeing == true)//关闭通道
                        {
                            try { subscription.UnSubscribeFromChannels(channel); }
                            catch { }
                        }
                        else
                        {
                            if (action != null)
                            {
                                action.Invoke(channel, msg);
                            }
                        }
                    }
                    catch (Exception exp)
                    {
                        ErrorLogHelper.WriteLine(-1, mqpath, "RedisSubscribe", string.Format("MQredis订阅通信消息,通道:{1},处理消息{0},订阅名:{2}出错", msg.NullToEmpty(), channelname, Name), exp);
                    }
                };
                subscription.SubscribeToChannels(channelname);
            }
        }
 private void CheckMqPathUpdate(ProducterContext context)
 {
     lock (_contextupdatelock)
     {
         string mqpath = "";
         try
         {
             if (context.Disposeing == true)
             {
                 return;
             }
             mqpath = context.ProducterInfo.MqPathModel.mqpath;
             //检查当前队列是否有更新,有更新则重启producter
             var lastupdatetime = GetLastUpdateTimeOfMqPath(context);
             if (context.LastMQPathUpdateTime < lastupdatetime || context.IsNeedReload)
             {
                 ProducterBLL bll = new ProducterBLL(); ProducterInfo productinfo = null;
                 SqlHelper.ExcuteSql(context.ProducterProvider.Config.ManageConnectString, (c) =>
                 {
                     productinfo = bll.GetProducterInfo(c, context.ProducterProvider.MQPath, context.ProducterProvider.ProducterName);
                 });
                 context.ProducterInfo.Update(productinfo);
                 context.IsNeedReload         = false;
                 context.LastMQPathUpdateTime = lastupdatetime;
                 redislistener.RedisServerIp  = ConfigHelper.RedisServer;
             }
             //检查发送错误,错误发生超过一分钟自动重启来解决错误状态
             if (context.SendMessageErrorTime != null && (DateTime.Now - context.SendMessageErrorTime) > TimeSpan.FromSeconds(SystemParamConfig.Producter_SendError_Clear_Time))
             {
                 context.IsNeedReload = true; context.SendMessageErrorTime = null;
             }
         }
         catch (Exception exp)
         {
             ErrorLogHelper.WriteLine(context.GetMQPathID(), context.GetMQPath(), "CheckMqPathUpdate", "生产者检测队列是否更新错误", exp);
         }
     }
 }
        /// <summary>
        /// 注册消息循环
        /// </summary>
        public void RegisterReceiveMQListener <T>(Action <BusinessMQResponse <T> > action)
        {
            try
            {
                if (Context != null)
                {
                    throw new BusinessMQException("当前实例不能打开多个Consumer监听");
                }
                PartitionIndexs = (from o in PartitionIndexs orderby o select o).Distinct().ToList();
                Context         = new ConsumerContext(); Context.ConsumerProvider = this;
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "RegisterReceiveMQListener", "消费者开始注册消息回调");
                //注册信息
                RegisterConsumerInfo();
                //注册消息回调
                Context.Listener = new ReceiveMessageListener(); Context.ActionInfo = new ConsumerActionInfo()
                {
                    Action = action, ReturnType = typeof(T)
                };
                Context.Listener.Register((c) =>
                {
                    BusinessMQResponse <T> r = new BusinessMQResponse <T>(); r.InnerObject = c; r.ObjMsg = ((MQMessage)c).MessageObj <T>();
                    action.Invoke(r);
                }, Context);
                DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "RegisterReceiveMQListener", "注册消费者监听成功");
                LogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "RegisterReceiveMQListener", "注册消费者监听成功");
            }
            catch (Exception exp)
            {
                ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "RegisterReceiveMQListener", "消费者注册MQ监听出错", exp);

                try
                {
                    this.Dispose();
                }
                catch { }
                throw exp;
            }
        }
示例#18
0
 private void Run()
 {
     while (!cancelSource.IsCancellationRequested)
     {
         bool issleep = true;
         try
         {
             issleep = TiggerMessagesTask();
             DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-Run", "消费者内部消息队列循环一轮完成");
         }
         catch (Exception exp)
         {
             ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ReceiveMessageQuque-Run", "消费者内部消息队列循环出错。", exp);
         }
         finally
         {
             if (issleep == true && !cancelSource.IsCancellationRequested)
             {
                 System.Threading.Thread.Sleep(SystemParamConfig.Consumer_ReceiveMessageQuque_Every_Sleep_Time * 1000);
             }
         }
     }
 }
 /// <summary>
 /// //顺序轮询节点获取节点及分区,从而达到负载均衡的目的
 /// </summary>
 /// <param name="sendmessagecount"></param>
 /// <returns></returns>
 public LoadBalanceNodeInfo GetLoadBalanceNodeInfo()
 {
     try
     {
         lock (_operatorlock)
         {
             LoadBalanceNodeInfo info = new LoadBalanceNodeInfo();
             var p = LoadBalance.GetLoadBalancePartitionInfo();
             if (p == null)
             {
                 return(null);
             }
             var partitionidinfo = PartitionRuleHelper.GetPartitionIDInfo(p.PartitionId);
             info.DataNodeModel = DataNodeModelDic[partitionidinfo.DataNodePartition]; info.MQPathPartitionModel = p.MQPathParitionModel;
             return(info);
         }
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(-1, "", "GetLoadBalanceNodeInfo", "生产者负载均衡出错", exp);
         throw exp;
     }
 }
示例#20
0
        public override LoadBalancePartitionInfo GetLoadBalancePartitionInfo()
        {
            System.Threading.Interlocked.Increment(ref SendMessageCount);
            if (SendMessageCount > 1000000000)
            {
                SendMessageCount = 1;
            }

            if (this.MQPathParitionModels.Count > 0)
            {
                LoadBalanceNodeInfo info = new LoadBalanceNodeInfo();
                int index = (SendMessageCount - 1) % MQPathParitionModels.Count; var partion = MQPathParitionModels[index]; var partitionidinfo = PartitionRuleHelper.GetPartitionIDInfo(partion.partitionid);
                return(new LoadBalancePartitionInfo()
                {
                    PartitionId = partion.partitionid, PartitionIndex = partion.partitionindex, MQPathParitionModel = partion
                });
            }
            else
            {
                ErrorLogHelper.WriteLine(-1, "", "SystemLoadBalance-LoadBalancePartitionInfo", "系统默认生产者负载均衡出错:当前可用分区数为0", new Exception());
                return(null);
            }
        }
示例#21
0
 //心跳任务
 private void HeartBeatTask()
 {
     lock (_heartbeatrunlock)
     {
         try
         {
             //更新节点心跳
             DB.ConsumerBLL bll = new DB.ConsumerBLL();
             SqlHelper.ExcuteSql(Context.ConsumerProvider.Config.ManageConnectString, (c) =>
             {
                 bll.ConsumerHeartbeat(c, Context.ConsumerInfo.ConsumerModel.tempid, Context.ConsumerInfo.ConsumerModel.consumerclientid);
             });
             DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect-HeartBeatTask", "更新节点心跳完毕");
             //检查当前队列是否有更新,有更新则重启customer
             var lastupdatetime = GetLastUpdateTimeOfMqPath();
             if (_lastupdatetimeofmqpath < lastupdatetime || Context.IsNeedReload == true)
             {
                 Context.IsNeedReload = false;
                 DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect-HeartBeatTask", "检测到队列更新准备重启");
                 //Context.ConsumerProvider.ReRegister();
                 Context.ConsumerProvider.Dispose();
                 MethodInfo method = typeof(ConsumerProvider).GetMethod("RegisterReceiveMQListener", BindingFlags.Instance | BindingFlags.Public);
                 method = method.MakeGenericMethod(Context.ActionInfo.ReturnType);
                 method.Invoke(Context.ConsumerProvider, new object[] { Context.ActionInfo.Action });
                 _lastupdatetimeofmqpath     = lastupdatetime;
                 redislistener.RedisServerIp = ConfigHelper.RedisServer;
                 DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect-HeartBeatTask", "检测到队列更新重启成功");
                 LogHelper.WriteLine(Context.ConsumerInfo.MQPathModel.id, Context.ConsumerInfo.MQPathModel.mqpath, "队列更新重启", "消费者检测到队列更新重启成功");
             }
         }
         catch (Exception exp)
         {
             ErrorLogHelper.WriteLine(Context.ConsumerInfo.MQPathModel.id, Context.ConsumerInfo.MQPathModel.mqpath, "HeartBeatTask", "消费者心跳循环出错", exp);
         }
     }
 }
示例#22
0
 private void RedisListenerCommand(string channel, string msg)
 {
     try
     {
         if (!cancelSource.IsCancellationRequested)
         {
             DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect-RedisListenerCommand", "检测到redis消息,msg:" + msg.NullToEmpty());
             var command = new XXF.Serialization.JsonHelper().Deserialize <BusinessMQNetCommand>(msg);
             if ((command.CommandReceiver == EnumCommandReceiver.All || command.CommandReceiver == EnumCommandReceiver.Consumer) && command.MqPath.ToLower() == Context.ConsumerProvider.MQPath.ToLower())
             {
                 if (command.CommandType == EnumCommandType.Register)
                 {
                     DebugHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "ConsumerHeartbeatProtect-RedisListenerCommand", "检测到redis消息:" + EnumCommandType.Register.Tostring());
                     Context.IsNeedReload = true;
                     HeartBeatTask();
                 }
             }
         }
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(Context.ConsumerInfo.MQPathModel.id, Context.ConsumerInfo.MQPathModel.mqpath, "RedisListenerCommand", "消费者Redis注册监听", exp);
     }
 }
示例#23
0
 /// <summary>
 /// 发送消息
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="objmsg"></param>
 public void SendMessage <T>(T objmsg)
 {
     try
     {
         var json = "";
         ProducterTimeWatchInfo.JsonHelperSerializer += Log.TimeWatchLog.Debug(() =>
         {
             if (!(objmsg is string))
             {
                 json = new Serialization.JsonHelper().Serializer(objmsg);
             }
             else
             {
                 json = objmsg as string;
             }
         });
         //发送消息有n次重试机会
         int errortrycount = 0;
         while (errortrycount < Context.ProducterInfo.LoadBalance.SendMessageErrorTryAgainCount)
         {
             LoadBalanceNodeInfo loadbalancenodeinfo = null;
             ProducterTimeWatchInfo.GetLoadBalanceNodeInfo += Log.TimeWatchLog.Debug(() =>
             {
                 loadbalancenodeinfo = Context.ProducterInfo.GetLoadBalanceNodeInfo();
             });
             if (loadbalancenodeinfo == null)
             {
                 throw new BusinessMQException(string.Format("无法获取队列{0}的可用的负载均衡数据节点", MQPath));
             }
             string datanodeconnectstring = new ProducterBLL().GetDataNodeConnectString(SystemParamConfig.Producter_DataNode_ConnectString_Template_ToSendMessage, loadbalancenodeinfo.DataNodeModel);
             var    partitionidinfo       = PartitionRuleHelper.GetPartitionIDInfo(loadbalancenodeinfo.MQPathPartitionModel.partitionid);
             var    manageservertime      = Context.ManageServerTime;//.AddSeconds(1);发送消息要比标准时间提前1s,这样消息分表可以提前1s
             string tablename             = PartitionRuleHelper.GetTableName(partitionidinfo.TablePartition, manageservertime);
             try
             {
                 ProducterTimeWatchInfo.SendMessage += Log.TimeWatchLog.Debug(() =>
                 {
                     double inserttime    = 0;
                     double allinserttime = Log.TimeWatchLog.Debug(() =>
                     {
                         inserttime = Log.TimeWatchLog.Debug(() =>
                         {
                             tb_messagequeue_dal dal = new tb_messagequeue_dal();
                             dal.TableName           = tablename;
                             SqlHelper.ExcuteSql(datanodeconnectstring, (c) =>
                             {
                                 dal.Add2(c, new tb_messagequeue_model()
                                 {
                                     message       = json,
                                     mqcreatetime  = DateTime.Now,
                                     sqlcreatetime = manageservertime
                                     ,
                                     source = (int)EnumMessageSource.Common,
                                     state  = (int)EnumMessageState.CanRead
                                 });
                             });
                         });
                     });
                     //ProducterTimeWatchTest.AddMessages(string.Format("总插入消息:{0}s,插入消息:{1}s",allinserttime,inserttime));
                 });
                 NetCommand.SendMessage(mqpath);
                 return;
             }
             catch (SqlException exp)
             {
                 ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "SendMessage", string.Format("发送消息出现节点错误,节点:{0}", loadbalancenodeinfo.DataNodeModel.datanodepartition), exp);
                 Context.ProducterInfo.RemoveMQPathPartition(loadbalancenodeinfo.DataNodeModel.datanodepartition);//数据层出错视为数据节点异常,则移除。将在一定时间内尝试恢复
                 Context.ProducterInfo.LoadBalance.AddError(new ErrorLoadBalancePartitionInfo()
                 {
                     PartitionId = loadbalancenodeinfo.MQPathPartitionModel.partitionid, PartitionIndex = loadbalancenodeinfo.MQPathPartitionModel.partitionindex
                 });
                 //Context.IsNeedReload = true;
                 if (Context.SendMessageErrorTime == null)
                 {
                     Context.SendMessageErrorTime = DateTime.Now;
                 }
             }
             errortrycount++;
         }
         throw new BusinessMQException(string.Format("发送消息出现系统级错误,并超过重试次数,请检查。队列:{0}", MQPath));
     }
     catch (Exception exp)
     {
         ErrorLogHelper.WriteLine(Context.GetMQPathID(), Context.GetMQPath(), "SendMessage", "生产者发送消息出错", exp);
         throw exp;
     }
 }