using System.Diagnostics; using System.Net; using Fake; using Fake.Messaging; using Fake.Messaging.RabbitMQ; using Fake.Modularity; using Fake.ObjectMapping.AutoMapper; using Fake.ObjectStorage; using FreeRedis; using Hangfire; using Hangfire.Redis.StackExchange; using InterfaceForward.Domain.Shared.Helpers; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using TrackCenter.Application.HostServices; using TrackCenter.Application.Kafka; using TrackCenter.Application.Messaging; using TrackCenter.Application.Options; namespace TrackCenter.Application; [DependsOn(typeof(FakeObjectMappingAutoMapperModule))] [DependsOn(typeof(FakeMessagingRabbitMqModule))] [DependsOn(typeof(FakeObjectStorageTencentCosModule))] [DependsOn(typeof(TrackCenterDomainModule))] public class TrackCenterApplicationModule : FakeModule { public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); context.Services.Configure(options => { options.ScanProfiles(); }); // Messaging:独立队列;PrefetchCount=0 → ProcessorCount;接口通可按 TrackApp:TrackRefreshFetchCount 覆盖 context.Services.Configure(configuration.GetSection(MessagingOptions.SectionName)); context.Services.Configure(o => { configuration.GetSection(RabbitMessageOptions.SectionName).Bind(o); var refreshFetch = configuration.GetValue("TrackApp:TrackRefreshFetchCount"); if (refreshFetch > 0) { o.Handlers[nameof(TrackRefreshEventHandler)] = new RabbitMessageHandlerOptions { PrefetchCount = refreshFetch }; o.Handlers[nameof(TrackPushCompletedEventHandler)] = new RabbitMessageHandlerOptions { PrefetchCount = refreshFetch }; } }); var redisOptions = configuration.GetSection("Redis").Get(); if (redisOptions == null) throw new FakeException("未找到Redis相关配置,请检查配置文件中是否包含名为Redis的节点"); RedisHelper.Init(redisOptions, showLogInfo: Debugger.IsAttached); context.Services.Configure(configuration.GetSection("TrackApp")); context.Services.Configure( configuration.GetSection("InterfaceRelayParamsConfig")); var connectionString = $"{configuration["Redis:Host"]}" + $",password={configuration["Redis:Password"]}" + $",defaultDatabase={configuration["Redis:Database"]}" + $",abortConnect=false"; // 注册预警计算服务 context.Services.AddWarningCalcServices(configuration); // 注册预警任务后台服务 context.Services.AddHostedService(); // 注册飞书服务(用于预警通知) context.Services.AddFeishuNetSdk(o => { o.AppId = configuration.GetValue("FeiShu:AppId")!; o.AppSecret = configuration.GetValue("FeiShu:AppSecret")!; o.EnableLogging = configuration.GetValue("FeiShu:EnableLogging"); }); // 注册HangFire服务 context.Services.Configure(configuration.GetSection("WarningTask")); context.Services.AddHangfire(o => { var options = new RedisStorageOptions { Prefix = $"{GlobalConst.TrackHangfireKeyPrefix}:", Db = int.Parse(configuration["Redis:Database"]!), }; o.UseRedisStorage(connectionString, options) .WithJobExpirationTimeout(TimeSpan.FromHours(1)); // 终止态任务只保留1小时 }); var hangfireWorkerCount = configuration.GetValue("TrackApp:HangfireWorkerCount"); if (hangfireWorkerCount <= 0) { hangfireWorkerCount = Math.Max(4, Environment.ProcessorCount); } context.Services.AddHangfireServer(o => { // 索引越小优先级越高 o.Queues = [ GlobalConst.WarningJobQueueLevel0, GlobalConst.WarningJobQueueLevel1, GlobalConst.WarningJobQueueLevel2, "default" ]; o.ServerName = Dns.GetHostName(); o.ShutdownTimeout = TimeSpan.FromSeconds(10); o.WorkerCount = hangfireWorkerCount; }); // 注册轨迹业务定时任务服务 context.Services.AddHostedService(); context.Services.AddHttpClient("itfx", client => { client.Timeout = TimeSpan.FromSeconds(20); client.BaseAddress = new Uri(configuration["TrackApp:ItfxBaseAddress"]!); }); } }