예제 #1
0
        /// <summary>
        /// 添加MQTransaction注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="optionsAction"></param>
        /// <returns></returns>
        public static IServiceCollection AddMQTransaction(this IServiceCollection services, Action <MQTransOptions> optionsaction)
        {
            var options = new MQTransOptions();

            //执行委托中方法
            optionsaction(options);

            options.CheckNull();

            //使委托中配置注入容器
            foreach (var register in options.Registers)
            {
                register.AddServices(services);
            }
            //注入全局配置
            services.AddSingleton(options);

            //注入job
            services.AddHostedService <PublishMsgHostService>();
            services.AddHostedService <QueryStatusHostService>();

            //注入消费端
            foreach (var consumer in options.ConsumerOptions)
            {
                services.AddScoped(consumer.ConsumerType);
            }
            //注入触发消费类
            services.AddScoped <ConsumeMessageWorker>();

            //http注入
            services.AddHttpClient();
            services.AddTransient <MQtransProxy>();

            return(services);
        }
예제 #2
0
 public EFMQPublisher(MQTransOptions options
                      , IServiceProvider serviceProvider
                      , EFOptions mySqlEFOptions
                      , IMQGenerateMsgBody mQGenerateMsgBody
                      , IMQTransRepository repository
                      , IMQOperate mQOperate)
 {
     this.options           = options;
     this.serviceProvider   = serviceProvider;
     this.mySqlEFOptions    = mySqlEFOptions;
     this.mQGenerateMsgBody = mQGenerateMsgBody;
     this.repository        = repository;
     this.mQOperate         = mQOperate;
 }
예제 #3
0
        public async Task DoAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                IMQTransRepository repository   = null;
                MQTransOptions     options      = null;
                MQtransProxy       mQtransProxy = null;

                try
                {
                    using (var scope = Services.CreateScope())
                    {
                        IMQTransRedis redis        = null;
                        RedisOptions  redisOptions = null;
                        var           logid        = Guid.NewGuid().ToString();

                        repository   = scope.ServiceProvider.GetService <IMQTransRepository>();
                        options      = scope.ServiceProvider.GetService <MQTransOptions>();
                        mQtransProxy = scope.ServiceProvider.GetService <MQtransProxy>();
                        redis        = scope.ServiceProvider.GetService <IMQTransRedis>();
                        redisOptions = scope.ServiceProvider.GetService <RedisOptions>();
                        _logger.LogInformation($"{logid}->查询消息JOB*BEGIN*{options.ServiceName}*{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");

                        var needSaveChange = false;
                        if (redis.LockTake(ConstValues.LockQueryMsg + options.ServiceName, ConstValues.LockQueryMsg + options.ServiceName, TimeSpan.FromSeconds(redisOptions.LockMsgSenconds)))
                        {
                            try
                            {
                                var needQueryMsgs = repository.GetDealingMsgs(500, options.ServiceName, options.DefaultRetryCount);

                                if (needQueryMsgs != null && needQueryMsgs.Count > 0)
                                {
                                    foreach (var request in needQueryMsgs)
                                    {
                                        var resultstr = await mQtransProxy.Post(request.query_url, new[] { request.id });

                                        if (!string.IsNullOrEmpty(resultstr))
                                        {
                                            var result = JsonConvert.DeserializeObject <List <QueryStatusRequest> >(resultstr);
                                            if (result != null)//找到了
                                            {
                                                var queryresult = result.Any(e => e.Id == request.id);
                                                repository.UpdateCallbackStatus(request, queryresult, options.DefaultRetryCount);
                                                needSaveChange = true;
                                            }
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError($"{logid}->查询消息JOB*{ex.ToString()}");
                            }
                            finally
                            {
                                if (needSaveChange)
                                {
                                    if (!repository.SaveChange())
                                    {
                                        _logger.LogError($"{logid}->发送消息JOB*保存失败");
                                    }
                                }

                                var a = redis.LockRelease(ConstValues.LockQueryMsg + options.ServiceName, ConstValues.LockQueryMsg + options.ServiceName);
                                _logger.LogInformation($"{logid}->查询消息JOB*END*{options.ServiceName}*{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError("查询消息JOB ERR:" + ex.ToString());
                }

                //3min
                Thread.Sleep(1000 * 60 * options.JobFrequencyMinute);
            }
        }
예제 #4
0
        public async Task DoAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                MQTransOptions     options         = null;
                IMQTransRepository repository      = null;
                IMQOperate         mqOperate       = null;
                IMQGenerateMsgBody generateMsgBody = null;

                try
                {
                    using (var scope = Services.CreateScope())
                    {
                        IMQTransRedis redis        = null;
                        RedisOptions  redisOptions = null;
                        var           logid        = Guid.NewGuid().ToString();
                        _logger.LogInformation($"{logid}->发送消息JOB*BEGIN*{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                        repository      = scope.ServiceProvider.GetService <IMQTransRepository>();
                        mqOperate       = scope.ServiceProvider.GetService <IMQOperate>();
                        generateMsgBody = scope.ServiceProvider.GetService <IMQGenerateMsgBody>();
                        options         = scope.ServiceProvider.GetService <MQTransOptions>();
                        redis           = scope.ServiceProvider.GetService <IMQTransRedis>();
                        redisOptions    = scope.ServiceProvider.GetService <RedisOptions>();
                        var needSaveChange = false;
                        if (redis.LockTake(ConstValues.LockSendMsg + options.ServiceName, options.ServiceName, TimeSpan.FromSeconds(redisOptions.LockMsgSenconds)))
                        {
                            var needPublishMsgs = repository.GetNeedPublishMsgs(100, options.ServiceName);
                            _logger.LogInformation($"{logid}->发送消息JOB*COUNT*{needPublishMsgs.Count}*{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                            try
                            {
                                foreach (var msg in needPublishMsgs)
                                {
                                    var result = mqOperate.DirectPublish(generateMsgBody.GenerateQueueConfig(msg), JsonConvert.DeserializeObject <Message>(msg.message));
                                    if (result.IsSucess)
                                    {
                                        needSaveChange = true;
                                        repository.UpdateSuccessStatus(msg, options.ExpiresMinute);
                                    }
                                    else
                                    {
                                        //发送失败,不做处理,会自动重新发起
                                        _logger.LogError($"{logid}->发送消息JOB*未发送成功{JsonConvert.SerializeObject(result)}");
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                //未查到,不做处理,会自动重新发起
                                _logger.LogError($"{logid}->发送消息JOB*{ex.ToString()}");
                            }
                            finally
                            {
                                if (needSaveChange)
                                {
                                    if (!repository.SaveChange())
                                    {
                                        _logger.LogError($"{logid}->发送消息JOB*保存失败");
                                    }
                                }

                                var a = redis.LockRelease(ConstValues.LockSendMsg + options.ServiceName, options.ServiceName);
                                _logger.LogError($"{logid}->发送消息JOB*END*{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError("发送消息JOB ERR:" + ex.ToString());
                }

                //3min
                Thread.Sleep(1000 * 60 * options.JobFrequencyMinute);
            }
        }
예제 #5
0
 /// <summary>
 /// 发消息时必填,防止分布式系统job重复执行。使用CSRedis操作redis。也可用其他,但需要开发
 /// </summary>
 /// <param name="options"></param>
 /// <param name="redisOptions"></param>
 public static void UseCSRedisRedis(this MQTransOptions options, RedisOptions redisOptions)
 {
     options.Regist(new CSRedisRegister(redisOptions));
 }
예제 #6
0
 /// <summary>
 /// 发消息时必填,防止分布式系统job重复执行。使用StackExchangeRedis操作redis。也可用其他,但需要开发
 /// </summary>
 /// <param name="options"></param>
 /// <param name="redisOptions"></param>
 public static void UseStackExchangeRedis(this MQTransOptions options, RedisOptions redisOptions)
 {
     options.Regist(new StackExchangeRedisRegister(redisOptions));
 }
예제 #7
0
 /// <summary>
 /// 使用RabbitMQ做消息。也可用Kafka,但需要开发
 /// </summary>
 /// <param name="options"></param>
 /// <param name="mqoptions"></param>
 public static void UseRabbitMQ(this MQTransOptions options, RabbitMQOptions mqoptions)
 {
     options.Regist(new RabbitMQRegister(mqoptions));
 }
예제 #8
0
 /// <summary>
 /// 使用EF存储。也可用Dapper等框架,但需要开发
 /// </summary>
 /// <typeparam name="TDbContext"></typeparam>
 /// <param name="options"></param>
 /// <param name="mysqption"></param>
 public static void UseEF <TDbContext>(this MQTransOptions options, EFOptions mysqption)
 {
     mysqption.MQDbContext = typeof(TDbContext);
     options.Regist(new EFRegister <TDbContext>(mysqption));
 }
예제 #9
0
 public ConsumeMessageWorker(IMQOperate mQOperate, MQTransOptions mQTransOptions)
 {
     this.mQOperate      = mQOperate;
     this.mQTransOptions = mQTransOptions;
 }
예제 #10
0
 public RabbitGenerateMsgBody(IMQOptions mqoptions, MQTransOptions options)
 {
     this.mqoptions = mqoptions as RabbitMQOptions;
     this.options   = options;
 }