コード例 #1
0
        /// <summary>
        /// 获取生产者实例并启动它,它和生产者服务类实例不是一个东西,请勿混淆
        /// </summary>
        /// <returns></returns>
        protected IONSProducer GetProducer()
        {
            IONSProducer producer = ONSHelper.ONSProducerList.Where(p => (p.Type == this.MessageType.ToString().ToUpper()) && (p.ProducerId == this.Pid)).FirstOrDefault();

            if (producer == null)
            {
                //生产者对象不存在,则新建

                lock (_lockHelper)
                {
                    producer = ONSHelper.ONSProducerList.Where(p => (p.Type == this.MessageType.ToString().ToUpper()) && (p.ProducerId == this.Pid)).FirstOrDefault();
                    if (producer == null)
                    {
                        ONSFactoryProperty onsProducerFactoryProperty = new ONSFactoryProperty();
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.AccessKey, _AliyunOnsAccessKey);
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.SecretKey, _AliyunOnsSecretKey);
                        //用老的.net SDK按最新的RocketMQ架构,引入GroupId代替ProducerId和ConsumerId
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.ProducerId, this.Pid);
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.PublishTopics, this.Topic);

                        producer = InitilizeProducer(onsProducerFactoryProperty);
                        ONSHelper.ONSProducerList.Add(producer);
                        producer.start();
                    }
                }
            }
            return(producer);
        }
コード例 #2
0
        /// <summary>
        /// 上游生产者的实现rocketmq的核心方法,其中会由rocketmq自动间接调用AbstractProducerService实例的InternalProduce方法
        /// </summary>
        /// <param name="model">接收的参数</param>
        /// <returns>事务执行结果</returns>
        public bool Process(T model)
        {
            if (_AliyunOnsIsAllowedToSend != "1")
            {
                return(false);
            }
            string requestTraceId = "";
            string key            = this.CreateMessageKey();
            string failureReason  = "";
            string body           = "";
            bool   accomplishment = false;
            int    producedTimes  = 0;
            int    errorTimes     = 0;

            try
            {
                //获取requestTraceId
                requestTraceId = this.GetRequestTraceId();
                //此方法中,只要是普通消息或顺序消息都是空实现,直接返回true
                InternalProcess(model);
                //序列化实体,即消息正文
                body = model.GetType().Name.ToLower() == "system.string" ? model.ToString() : JsonConvert.SerializeObject(model);
                //防止中文乱码
                body = Base64Util.Encode(body);
                //获取生产者
                IONSProducer producer = GetProducer();
                //生成消息实体
                Message message = new Message(this.Topic, this.Tag, body);
                message.setKey(key);
                message.putUserProperties("type", this.MessageType.ToString());
                message.putUserProperties("requestTraceId", requestTraceId);
                //message.putUserProperties("shardingKey", shardingKey);
                //定义消息结果对象
                SendResultONS sendResultONS = null;
                //尝试发送
                sendResultONS = TryToSend(producer, message, null, key, errorTimes);
                //判断结果,一般走不到这步,因为如果发送有问题会直接抛出异常的
                if (sendResultONS == null)
                {
                    throw new Exception("发送BASE消息失败。key=" + key);
                }
                //更新发送状态
                accomplishment = true;
                //更新消费次数
                producedTimes = 1;
            }
            catch (Exception e)
            {
                //将内部捕捉的错误赋值给failureReason,然后由ProduceData的FailureReason属性统一处理
                failureReason = "发送BASE消息,key=" + key + ",捕捉异常:" + e.ToString();
                return(false);
            }
            finally
            {
                //无论是否有异常都统一写入生产日志
                LogData(key, body, "", "", failureReason, accomplishment, producedTimes, failureReason != "" ? false : true);
            }
            return(true);
        }
コード例 #3
0
        /// <summary>
        /// 尝试发送消息
        /// </summary>
        /// <param name="producer">生产者实例</param>
        /// <param name="message">消息实例</param>
        /// <param name="parameter">发送所需参数</param>
        /// <param name="key">消息的唯一标识</param>
        /// <param name="errorTimes">本系统自己自己执行时发现出错后,记录的错误次数(此参数不适用于生产次数)</param>
        /// <returns></returns>
        protected SendResultONS TryToSend(IONSProducer producer, Message message, object parameter, string key, int errorTimes)
        {
            SendResultONS sendResultONS = null;

            try
            {
                sendResultONS = producer.send(message, parameter);
            }
            catch (Exception e)
            {
                //错误计数累加
                errorTimes++;
                //无论是阿里云服务不可用,还是生产者挂了,一共3次机会,即执行1次,然后最多重试两次
                if (errorTimes < 3)
                {
                    //如果生产者挂了
                    if (e.ToString().IndexOf("Your producer has been shutdown.") >= 0)
                    {
                        //置空producer
                        producer = null;
                        //重新获取producer并启动
                        producer = GetProducer();
                        //等待3秒
                        System.Threading.Thread.Sleep(3000);
                    }
                    else
                    {
                        //如果是阿里云服务不可用,等待1秒
                        System.Threading.Thread.Sleep(1000);
                    }

                    //递归
                    sendResultONS = TryToSend(producer, message, parameter, key, errorTimes);
                }
                else
                {
                    //重试2次都还是失败
                    string className    = this.GetType().Name;
                    string methodName   = "Process";
                    string errorMessage = _Environment + "." + _ApplicationAlias + "." + className + "." + methodName + "尝试发送时,出现了第" + errorTimes + "次出错,key=" + key + ":" + e.ToString();
                    //记录本地错误日志
                    DebugUtil.Debug(errorMessage);
                    //记录FATAL日志
                    ONSHelper.SaveLog(LogTypeEnum.FATAL, className, methodName, errorMessage);
                    //发送邮件
                    ONSHelper.SendDebugMail(_Environment + "." + _ApplicationAlias + "." + className + "." + methodName + "尝试发送时出错", errorMessage);
                    //抛出异常
                    throw new Exception(errorMessage);
                }
            }

            return(sendResultONS);
        }
コード例 #4
0
        /// <summary>
        /// 创建生产者实例
        /// </summary>
        /// <typeparam name="T">生产者服务基类类型</typeparam>
        /// <param name="assembly">生产者服务类所在程序集</param>
        /// <param name="type">生产者服务类的类型</param>
        /// <param name="messageType">消息类型BASE,ORDER,TRAN</param>
        /// <param name="func">生成生产者实例的委托代码</param>
        internal static void CreateProducer <T>(Assembly assembly, Type type, ONSMessageType messageType, Func <ONSFactoryProperty, string, string, IONSProducer> func)
        {
            if (type.BaseType.FullName.IndexOf(typeof(T).Name) >= 0)
            {
                //添加到生产者服务类实例列表
                //ONSProducerServiceList.Add(type);
                object service = assembly.CreateInstance(type.FullName);
                ONSProducerServiceList.Add(service);
                //获取服务接口
                IAbstractProducerService iservice = (IAbstractProducerService)service;
                //获取枚举对象
                Enum topicTag = iservice.TopicTag;

                if (topicTag != null)
                {
                    string serviceTopic = topicTag.GetType().Name;
                    string topic        = (_Environment + "_" + serviceTopic).ToUpper();
                    //string producerId = ("PID_" + topic).ToUpper();
                    string       producerId = ("GID_" + topic).ToUpper();
                    IONSProducer producer   = ONSProducerList.Where(p => (p.Type == messageType.ToString()) && (p.ProducerId == producerId)).FirstOrDefault();
                    if (producer == null)
                    {
                        //实例化ONSFactoryProperty
                        ONSFactoryProperty onsProducerFactoryProperty = new ONSFactoryProperty();
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.AccessKey, _AliyunOnsAccessKey);
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.SecretKey, _AliyunOnsSecretKey);
                        //用老的.net SDK按最新的RocketMQ架构,引入GroupId代替ProducerId和ConsumerId
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.ProducerId, producerId);
                        onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.PublishTopics, topic);

                        if (_AliyunOnsProducerLogPath != "")
                        {
                            if (Directory.Exists(_AliyunOnsProducerLogPath))
                            {
                                onsProducerFactoryProperty.setFactoryProperty(ONSFactoryProperty.LogPath, _AliyunOnsProducerLogPath);
                            }
                        }

                        //获取生产者IONSProducer
                        producer = func(onsProducerFactoryProperty, topic, producerId);

                        //记录生产者初始化信息
                        DebugUtil.Debug("Topic:" + topic + ",ProducerId(" + producer.Type.ToString() + "):" + producer.ProducerId + "生产者new()");

                        //新增代理类ONSProducer实例到ONSProducerList中
                        ONSProducerList.Add(producer);
                    }
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// 上游生产者的实现rocketmq的核心方法,其中会由rocketmq自动间接调用AbstractTransactionProducerService实例的InternalProduce方法
        /// </summary>
        /// <param name="model">接收的参数</param>
        /// <returns>事务执行结果</returns>
        public bool Process(T model)
        {
            if (_AliyunOnsIsAllowedToSend != "1")
            {
                return(false);
            }
            string requestTraceId = "";
            string key            = this.CreateMessageKey();
            string failureReason  = "";
            string body           = "";
            bool   accomplishment = false;
            int    producedTimes  = 0;
            int    errorTimes     = 0;

            try
            {
                //获取requestTraceId
                requestTraceId = this.GetRequestTraceId();
                //序列化实体,即消息正文
                body = model.GetType().Name.ToLower() == "system.string" ? model.ToString() : JsonConvert.SerializeObject(model);
                //防止中文乱码
                body = Base64Util.Encode(body);
                //获取生产者
                IONSProducer producer = GetProducer();
                //Message实体的body不能为空
                Message message = new Message(this.Topic, this.Tag, body);
                message.setKey(key);
                message.putUserProperties("type", this.MessageType.ToString());
                message.putUserProperties("requestTraceId", requestTraceId);

                //获取InternalProcess方法
                MethodInfo methodInfo = this.GetType().GetMethod("InternalProcess", BindingFlags.NonPublic | BindingFlags.Instance);

                string executerMethodName = methodInfo.ReflectedType.FullName + "." + methodInfo.Name;
                string checkerMethodName  = methodInfo.ReflectedType.FullName + "." + methodInfo.Name;

                //将方式实例和方式实例的参数都存到消息的属性中去。
                //message.putUserProperties("executerMethodParameter", data);
                message.putUserProperties("executerMethod", executerMethodName);
                //message.putUserProperties("checkerMethodParameter", data);
                message.putUserProperties("checkerMethod", checkerMethodName);

                //方式实例字典中不存在的话,则试图新增到字典中去
                if (!ONSHelper.ExecuterMethodDictionary.ContainsKey(executerMethodName))
                {
                    ONSHelper.ExecuterMethodDictionary.TryAdd(executerMethodName, methodInfo);
                }
                if (!ONSHelper.CheckerMethodDictionary.ContainsKey(checkerMethodName))
                {
                    ONSHelper.CheckerMethodDictionary.TryAdd(checkerMethodName, methodInfo);
                }

                //实例化LocalTransactionExecuter对象
                ONSLocalTransactionExecuter executer = new ONSLocalTransactionExecuter();
                //定义消息结果对象
                SendResultONS sendResultONS = null;
                //尝试发送
                sendResultONS = TryToSend(producer, message, executer, key, errorTimes);
                //判断结果,一般走不到这步,因为如果发送有问题会直接抛出异常的
                if (sendResultONS == null)
                {
                    throw new Exception("发送TRAN消息失败。key=" + key);
                }
                //更新发送状态
                accomplishment = true;
                //更新消费次数
                producedTimes = 1;
            }
            catch (Exception e)
            {
                failureReason = "发送TRAN消息,key=" + key + ",在TranProducerService中(非Executer或Checker中),捕获异常" + e.ToString();
                LogData(key, body, "", "", failureReason, accomplishment, producedTimes, false);
                return(false);
            }

            return(true);
        }