Browse Source

feat(tasks): 增强多租户支持.

pull/463/head
cKey 4 years ago
parent
commit
8269ba8395
  1. 12
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs
  2. 4
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/AbpBackgroundTasksQuartzModule.cs
  3. 10
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/IQuartzKeyBuilder.cs
  4. 16
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs
  5. 21
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobScheduler.cs
  6. 35
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzKeyBuilder.cs
  7. 15
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundCleaningJob.cs
  8. 2
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundKeepAliveJob.cs
  9. 28
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundPollingJob.cs
  10. 11
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs
  11. 3
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs
  12. 140
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs
  13. 5
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj
  14. 50
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs
  15. 6
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs
  16. 13
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/appsettings.Development.json

12
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs

@ -41,6 +41,18 @@ public static class JobRunnableContextExtensions
return false;
}
public static bool TryGetMultiTenantId(this JobRunnableContext context, out Guid? tenantId)
{
tenantId = null;
if (context.TryGetString(nameof(JobInfo.TenantId), out var tenantUUIdString) &&
Guid.TryParse(tenantUUIdString, out var tenantUUId))
{
tenantId = tenantUUId;
return true;
}
return false;
}
public static T GetJobData<T>(this JobRunnableContext context, string key) where T : struct
{
var value = context.GetJobData(key);

4
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/AbpBackgroundTasksQuartzModule.cs

@ -1,5 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using System.Collections.Specialized;
using Volo.Abp;
using Volo.Abp.Modularity;
using Volo.Abp.Quartz;

10
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/IQuartzKeyBuilder.cs

@ -0,0 +1,10 @@
using Quartz;
namespace LINGYUN.Abp.BackgroundTasks.Quartz;
public interface IQuartzKeyBuilder
{
JobKey CreateJobKey(JobInfo jobInfo);
TriggerKey CreateTriggerKey(JobInfo jobInfo);
}

16
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs

@ -15,20 +15,22 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD
protected IClock Clock { get; }
protected AbpBackgroundTasksOptions Options { get; }
protected IQuartzKeyBuilder KeyBuilder { get; }
public QuartzJobExecutorProvider(
IClock clock,
IQuartzKeyBuilder keyBuilder,
IOptions<AbpBackgroundTasksOptions> options)
{
Clock = clock;
Options = options.Value;
KeyBuilder = keyBuilder;
Logger = NullLogger<QuartzJobExecutorProvider>.Instance;
}
public IJobDetail CreateJob(JobInfo job)
{
var jobType = Type.GetType(job.Type) ?? Options.JobProviders.GetOrDefault(job.Type);
var jobType = Options.JobProviders.GetOrDefault(job.Type) ?? Type.GetType(job.Type);
if (jobType == null)
{
Logger.LogWarning($"The task: {job.Group} - {job.Name}: {job.Type} is not registered and cannot create an instance of the performer type.");
@ -50,7 +52,7 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD
// 改为 JobId作为名称
var jobBuilder = JobBuilder.Create(jobType)
.WithIdentity(job.Id.ToString(), job.Group)
.WithIdentity(KeyBuilder.CreateJobKey(job))
.WithDescription(job.Description);
jobBuilder.UsingJobData(nameof(JobInfo.Id), job.Id);
@ -82,10 +84,10 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD
return null;
}
triggerBuilder
.WithIdentity(job.Id.ToString(), job.Group)
.WithIdentity(KeyBuilder.CreateTriggerKey(job))
.WithDescription(job.Description)
.EndAt(job.EndTime)
.ForJob(job.Id.ToString(), job.Group)
.ForJob(KeyBuilder.CreateJobKey(job))
.WithPriority((int)job.Priority)
.WithCronSchedule(job.Cron);
if (job.BeginTime > Clock.Now)
@ -111,11 +113,11 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD
}
triggerBuilder
.WithIdentity(job.Id.ToString(), job.Group)
.WithIdentity(KeyBuilder.CreateTriggerKey(job))
.WithDescription(job.Description)
.StartAt(Clock.Now.AddSeconds(job.Interval))
.EndAt(job.EndTime)
.ForJob(job.Id.ToString(), job.Group)
.ForJob(KeyBuilder.CreateJobKey(job))
.WithPriority((int)job.Priority)
.WithSimpleSchedule(x =>
x.WithIntervalInSeconds(job.Interval)

21
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobScheduler.cs

@ -10,27 +10,29 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency
{
protected IJobStore JobStore { get; }
protected IScheduler Scheduler { get; }
protected IQuartzKeyBuilder KeyBuilder { get; }
protected IQuartzJobExecutorProvider QuartzJobExecutor { get; }
public QuartzJobScheduler(
IJobStore jobStore,
IScheduler scheduler,
IQuartzKeyBuilder keyBuilder,
IQuartzJobExecutorProvider quartzJobExecutor)
{
JobStore = jobStore;
Scheduler = scheduler;
KeyBuilder = keyBuilder;
QuartzJobExecutor = quartzJobExecutor;
}
public virtual async Task<bool> ExistsAsync(JobInfo job)
{
var jobKey = new JobKey(job.Id.ToString(), job.Group);
return await Scheduler.CheckExists(jobKey);
return await Scheduler.CheckExists(BuildJobKey(job));
}
public virtual async Task PauseAsync(JobInfo job)
{
var jobKey = new JobKey(job.Id.ToString(), job.Group);
var jobKey = BuildJobKey(job);
if (await Scheduler.CheckExists(jobKey))
{
var triggers = await Scheduler.GetTriggersOfJob(jobKey);
@ -43,7 +45,7 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency
public virtual async Task<bool> QueueAsync(JobInfo job)
{
var jobKey = new JobKey(job.Id.ToString(), job.Group);
var jobKey = BuildJobKey(job);
if (await Scheduler.CheckExists(jobKey))
{
return false;
@ -91,7 +93,7 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency
public virtual async Task<bool> RemoveAsync(JobInfo job)
{
var jobKey = new JobKey(job.Id.ToString(), job.Group);
var jobKey = BuildJobKey(job);
if (!await Scheduler.CheckExists(jobKey))
{
return false;
@ -109,7 +111,7 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency
public virtual async Task ResumeAsync(JobInfo job)
{
var jobKey = new JobKey(job.Id.ToString(), job.Group);
var jobKey = BuildJobKey(job);
if (await Scheduler.CheckExists(jobKey))
{
var triggers = await Scheduler.GetTriggersOfJob(jobKey);
@ -150,7 +152,7 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency
public virtual async Task TriggerAsync(JobInfo job)
{
var jobKey = new JobKey(job.Id.ToString(), job.Group);
var jobKey = BuildJobKey(job);
if (!await Scheduler.CheckExists(jobKey))
{
await QueueAsync(job);
@ -160,4 +162,9 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency
await Scheduler.TriggerJob(jobKey);
}
}
private JobKey BuildJobKey(JobInfo job)
{
return KeyBuilder.CreateJobKey(job);
}
}

35
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzKeyBuilder.cs

@ -0,0 +1,35 @@
using Quartz;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.BackgroundTasks.Quartz;
public class QuartzKeyBuilder : IQuartzKeyBuilder, ISingletonDependency
{
protected ICurrentTenant CurrentTenant { get; }
public QuartzKeyBuilder(ICurrentTenant currentTenant)
{
CurrentTenant = currentTenant;
}
public JobKey CreateJobKey(JobInfo jobInfo)
{
var name = jobInfo.Id.ToString();
var group = CurrentTenant.IsAvailable
? $"{CurrentTenant.Id}:{jobInfo.Group}"
: $"Default:{jobInfo.Group}";
return new JobKey(name, group);
}
public TriggerKey CreateTriggerKey(JobInfo jobInfo)
{
var name = jobInfo.Id.ToString();
var group = CurrentTenant.IsAvailable
? $"{CurrentTenant.Id}:{jobInfo.Group}"
: $"Default:{jobInfo.Group}";
return new TriggerKey(name, group);
}
}

15
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundCleaningJob.cs

@ -2,19 +2,26 @@
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.BackgroundTasks.Internal;
[DisableAuditing]
internal class BackgroundCleaningJob : IJobRunnable
public class BackgroundCleaningJob : IJobRunnable
{
public virtual async Task ExecuteAsync(JobRunnableContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundTasksOptions>>().Value;
var store = context.ServiceProvider.GetRequiredService<IJobStore>();
var currentTenant = context.ServiceProvider.GetRequiredService<ICurrentTenant>();
await store.CleanupAsync(
options.MaxJobCleanCount,
options.JobExpiratime);
context.TryGetMultiTenantId(out var tenantId);
using (currentTenant.Change(tenantId))
{
await store.CleanupAsync(
options.MaxJobCleanCount,
options.JobExpiratime);
}
}
}

2
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundKeepAliveJob.cs

@ -6,7 +6,7 @@ using Volo.Abp.Auditing;
namespace LINGYUN.Abp.BackgroundTasks.Internal;
[DisableAuditing]
internal class BackgroundKeepAliveJob : IJobRunnable
public class BackgroundKeepAliveJob : IJobRunnable
{
public virtual async Task ExecuteAsync(JobRunnableContext context)
{

28
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundPollingJob.cs

@ -3,32 +3,36 @@ using Microsoft.Extensions.Options;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.BackgroundTasks.Internal;
[DisableAuditing]
internal class BackgroundPollingJob : IJobRunnable
public class BackgroundPollingJob : IJobRunnable
{
public virtual async Task ExecuteAsync(JobRunnableContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundTasksOptions>>().Value;
var store = context.ServiceProvider.GetRequiredService<IJobStore>();
var currentTenant = context.ServiceProvider.GetRequiredService<ICurrentTenant>();
// TODO: 如果积压有大量持续性任务, 可能后面的队列无法被检索到
// 尽量让任务重复次数在可控范围内
// 需要借助队列提供者来持久化已入队任务
var waitingJobs = await store.GetWaitingListAsync(options.MaxJobFetchCount);
context.TryGetMultiTenantId(out var tenantId);
if (!waitingJobs.Any())
using (currentTenant.Change(tenantId))
{
return;
}
var waitingJobs = await store.GetWaitingListAsync(options.MaxJobFetchCount);
var jobScheduler = context.ServiceProvider.GetRequiredService<IJobScheduler>();
if (!waitingJobs.Any())
{
return;
}
foreach (var job in waitingJobs)
{
await jobScheduler.QueueAsync(job);
var jobScheduler = context.ServiceProvider.GetRequiredService<IJobScheduler>();
foreach (var job in waitingJobs)
{
await jobScheduler.QueueAsync(job);
}
}
}
}

11
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs

@ -25,9 +25,12 @@ internal class DefaultBackgroundWorker : BackgroundService
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
// 仅轮询宿主端
await QueuePollingJob();
await QueueKeepAliveJob();
await QueueCleaningJob();
// 周期性任务改为手动入队
// await QueueKeepAliveJob();
}
private async Task QueueKeepAliveJob()
@ -54,7 +57,7 @@ internal class DefaultBackgroundWorker : BackgroundService
{
Id = Guid.Parse("8F50C5D9-5691-4B99-A52B-CABD91D93C89"),
Name = nameof(BackgroundKeepAliveJob),
Group = "Default",
Group = "KeepAlive",
Description = "Add periodic tasks",
Args = new Dictionary<string, object>(),
Status = JobStatus.Running,
@ -74,7 +77,7 @@ internal class DefaultBackgroundWorker : BackgroundService
{
Id = Guid.Parse("C51152E9-F0B8-4252-8352-283BE46083CC"),
Name = nameof(BackgroundPollingJob),
Group = "Default",
Group = "Polling",
Description = "Polling tasks to be executed",
Args = new Dictionary<string, object>(),
Status = JobStatus.Running,
@ -94,7 +97,7 @@ internal class DefaultBackgroundWorker : BackgroundService
{
Id = Guid.Parse("AAAF8783-FA06-4CF9-BDCA-11140FB2478F"),
Name = nameof(BackgroundCleaningJob),
Group = "Default",
Group = "Cleaning",
Description = "Cleaning tasks to be executed",
Args = new Dictionary<string, object>(),
Status = JobStatus.Running,

3
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs

@ -131,7 +131,8 @@ public class BackgroundJobStore : IJobStore, ITransientDependency
eventData.Type.Name,
eventData.Group,
eventData.Name,
eventData.RunTime)
eventData.RunTime,
eventData.TenantId)
{
JobId = eventData.Key
};

140
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs

@ -0,0 +1,140 @@
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.BackgroundTasks.Internal;
using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.MultiTenancy;
using LY.MicroService.TaskManagement.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement;
using Volo.Abp.Uow;
namespace LY.MicroService.TaskManagement.EventBus.Handlers
{
public class TenantSynchronizer :
IDistributedEventHandler<CreateEventData>,
IDistributedEventHandler<EntityDeletedEto<TenantEto>>,
ITransientDependency
{
protected ILogger<TenantSynchronizer> Logger { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IDbSchemaMigrator DbSchemaMigrator { get; }
protected AbpBackgroundTasksOptions Options { get; }
protected IJobScheduler JobScheduler { get; }
public TenantSynchronizer(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IDbSchemaMigrator dbSchemaMigrator,
IOptions<AbpBackgroundTasksOptions> options,
IJobScheduler jobScheduler,
ILogger<TenantSynchronizer> logger)
{
CurrentTenant = currentTenant;
UnitOfWorkManager = unitOfWorkManager;
DbSchemaMigrator = dbSchemaMigrator;
JobScheduler = jobScheduler;
Options = options.Value;
Logger = logger;
}
public async Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData)
{
// 租户删除时移除轮询作业
var pollingJob = BuildPollingJobInfo(eventData.Entity.Id, eventData.Entity.Name);
await JobScheduler.RemoveAsync(pollingJob);
var cleaningJob = BuildCleaningJobInfo(eventData.Entity.Id, eventData.Entity.Name);
await JobScheduler.RemoveAsync(cleaningJob);
}
public async Task HandleEventAsync(CreateEventData eventData)
{
await MigrateAsync(eventData);
// 持久层介入之后提供对于租户的后台工作者轮询作业
await QueueBackgroundJobAsync(eventData);
}
private async Task QueueBackgroundJobAsync(CreateEventData eventData)
{
var pollingJob = BuildPollingJobInfo(eventData.Id, eventData.Name);
await JobScheduler.QueueAsync(pollingJob);
var cleaningJob = BuildCleaningJobInfo(eventData.Id, eventData.Name);
await JobScheduler.QueueAsync(cleaningJob);
}
private async Task MigrateAsync(CreateEventData eventData)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
using (CurrentTenant.Change(eventData.Id, eventData.Name))
{
Logger.LogInformation("Migrating the new tenant database with localization..");
// 迁移租户数据
await DbSchemaMigrator.MigrateAsync<TaskManagementMigrationsDbContext>(
(connectionString, builder) =>
{
builder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
return new TaskManagementMigrationsDbContext(builder.Options);
});
await unitOfWork.SaveChangesAsync();
Logger.LogInformation("Migrated the new tenant database with localization.");
}
}
}
private JobInfo BuildPollingJobInfo(Guid tenantId, string tenantName)
{
return new JobInfo
{
Id = tenantId,
Name = nameof(BackgroundPollingJob),
Group = "Polling",
Description = "Polling tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobFetchCronExpression,
JobType = JobType.Period,
Priority = JobPriority.High,
LockTimeOut = Options.JobFetchLockTimeOut,
TenantId = tenantId,
Type = typeof(BackgroundPollingJob).AssemblyQualifiedName,
};
}
private JobInfo BuildCleaningJobInfo(Guid tenantId, string tenantName)
{
return new JobInfo
{
Id = tenantId,
Name = nameof(BackgroundCleaningJob),
Group = "Cleaning",
Description = "Cleaning tasks to be executed",
Args = new Dictionary<string, object>() { { nameof(JobInfo.TenantId), tenantId } },
Status = JobStatus.Running,
BeginTime = DateTime.Now,
CreationTime = DateTime.Now,
Cron = Options.JobCleanCronExpression,
JobType = JobType.Period,
Priority = JobPriority.High,
TenantId = tenantId,
Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName,
};
}
}
}

5
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj

@ -19,12 +19,16 @@
<ItemGroup>
<PackageReference Include="AgileConfig.Client" Version="$(AgileConfigClientPackageVersion)" />
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="$(MicrosoftPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(MicrosoftPackageVersion)" />
<PackageReference Include="DistributedLock.Redis" Version="$(DistributedLockRedisPackageVersion)" />
<PackageReference Include="Quartz.Serialization.Json" Version="3.3.3" />
<PackageReference Include="Serilog.AspNetCore" Version="$(SerilogAspNetCorePackageVersion)" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="$(SerilogEnrichersEnvironmentPackageVersion)" />
<PackageReference Include="Serilog.Enrichers.Assembly" Version="$(SerilogEnrichersAssemblyPackageVersion)" />
@ -50,6 +54,7 @@
<ItemGroup>
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.BackgroundTasks.ExceptionHandling\LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.BackgroundTasks.Jobs\LINGYUN.Abp.BackgroundTasks.Jobs.csproj" />

50
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs

@ -12,6 +12,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using Volo.Abp;
@ -22,7 +24,10 @@ using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Quartz;
using Volo.Abp.VirtualFileSystem;
using Quartz;
using DotNetCore.CAP;
namespace LY.MicroService.TaskManagement;
@ -41,6 +46,51 @@ public partial class TaskManagementHttpApiHostModule
});
}
private void PreConfigureCAP(IConfiguration configuration)
{
PreConfigure<CapOptions>(options =>
{
options
.UseMySql(mySqlOptions =>
{
configuration.GetSection("CAP:MySql").Bind(mySqlOptions);
})
.UseRabbitMQ(rabbitMQOptions =>
{
configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions);
})
.UseDashboard();
});
}
private void PreConfigureQuartz(IConfiguration configuration)
{
PreConfigure<AbpQuartzOptions>(options =>
{
// 如果使用持久化存储, 则配置quartz持久层
if (configuration.GetSection("Quartz:UsePersistentStore").Get<bool>())
{
var settings = configuration.GetSection("Quartz:Properties").Get<Dictionary<string, string>>();
if (settings != null)
{
foreach (var setting in settings)
{
options.Properties[setting.Key] = setting.Value;
}
}
options.Configurator += (config) =>
{
config.UsePersistentStore(store =>
{
store.UseProperties = false;
store.UseJsonSerializer();
});
};
}
});
}
private void ConfigureDistributedLock(IServiceCollection services, IConfiguration configuration)
{
var redis = ConnectionMultiplexer.Connect(configuration["DistributedLock:Redis:Configuration"]);

6
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs

@ -3,6 +3,7 @@ using LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
using LINGYUN.Abp.BackgroundTasks.Jobs;
using LINGYUN.Abp.BackgroundTasks.Quartz;
using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore;
using LINGYUN.Abp.MultiTenancy.DbFinder;
@ -57,6 +58,7 @@ namespace LY.MicroService.TaskManagement;
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpTenantManagementEntityFrameworkCoreModule),
typeof(AbpLocalizationManagementEntityFrameworkCoreModule),
typeof(AbpCAPEventBusModule),
typeof(AbpDataDbMigratorModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpAspNetCoreMvcModule),
@ -67,7 +69,11 @@ public partial class TaskManagementHttpApiHostModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
PreConfigureApp();
PreConfigureCAP(configuration);
PreConfigureQuartz(configuration);
}
public override void ConfigureServices(ServiceConfigurationContext context)

13
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/appsettings.Development.json

@ -31,6 +31,19 @@
"VirtualHost": "/"
}
},
"Quartz": {
"UsePersistentStore": false,
"Properties": {
"quartz.jobStore.dataSource": "tkm",
"quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz",
"quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz",
"quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"quartz.dataSource.tkm.connectionStringName": "TaskManagement",
"quartz.dataSource.tkm.provider": "MySqlConnector",
"quartz.jobStore.clustered": "true",
"quartz.serializer.type": "json"
}
},
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"TaskManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",

Loading…
Cancel
Save