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 } } }
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); } }
/// <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; } }
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; } }
/// <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; } }
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; } }
//心跳循环 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; } }
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; } } } }
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; } }
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; } }
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); } }
//心跳任务 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); } } }
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); } }
/// <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; } }