diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs index 7aba4c48..255377ad 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs @@ -4,7 +4,9 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; using Yi.Framework.Bbs.Domain.Shared.Caches; +using Yi.Framework.Bbs.Domain.Shared.Etos; namespace Yi.Framework.Bbs.Application.Extensions; @@ -14,6 +16,29 @@ namespace Yi.Framework.Bbs.Application.Extensions; /// 需考虑一致性问题,又不能上锁影响性能 /// public class AccessLogMiddleware : IMiddleware, ITransientDependency +{ + private static int _accessLogNumber = 0; + + internal static void ResetAccessLogNumber() + { + _accessLogNumber = 0; + } + internal static int GetAccessLogNumber() + { + return _accessLogNumber; + } + + + public async Task InvokeAsync(HttpContext context, RequestDelegate next) + { + await next(context); + + Interlocked.Increment(ref _accessLogNumber); + } +} + +public class AccessLogResetEventHandler : ILocalEventHandler, + ITransientDependency { /// /// 缓存前缀 @@ -39,13 +64,28 @@ public class AccessLogMiddleware : IMiddleware, ITransientDependency return redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled); } } - - public async Task InvokeAsync(HttpContext context, RequestDelegate next) + + //该事件由job定时10秒触发 + public async Task HandleEventAsync(AccessLogResetArgs eventData) { - await next(context); if (EnableRedisCache) { - await RedisClient.IncrByAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date}", 1); + //分布式锁 + if (await RedisClient.SetNxAsync("AccessLogLock",true,TimeSpan.FromSeconds(5))) + { + //自增长数 + var incrNumber= AccessLogMiddleware.GetAccessLogNumber(); + //立即重置,开始计算,方式丢失 + AccessLogMiddleware.ResetAccessLogNumber(); + if (incrNumber>0) + { + await RedisClient.IncrByAsync( + $"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.ToString("yyyyMMdd")}", incrNumber); + } + + + } + } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs new file mode 100644 index 00000000..8f936574 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogCacheJob.cs @@ -0,0 +1,38 @@ +using FreeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using Quartz; +using Volo.Abp.BackgroundWorkers.Quartz; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities; +using Volo.Abp.EventBus.Local; +using Yi.Framework.Bbs.Domain.Entities; +using Yi.Framework.Bbs.Domain.Shared.Caches; +using Yi.Framework.Bbs.Domain.Shared.Enums; +using Yi.Framework.Bbs.Domain.Shared.Etos; +using Yi.Framework.SqlSugarCore.Abstractions; + +namespace Yi.Framework.Bbs.Application.Jobs; + +public class AccessLogCacheJob : QuartzBackgroundWorkerBase +{ + private readonly ILocalEventBus _localEventBus; + + public AccessLogCacheJob(ILocalEventBus localEventBus) + { + _localEventBus = localEventBus; + JobDetail = JobBuilder.Create().WithIdentity(nameof(AccessLogCacheJob)) + .Build(); + + //每10秒执行一次,将本地缓存转入redis,防止丢数据 + Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogCacheJob)) + .WithSimpleSchedule((schedule) => { schedule.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever();; }) + .Build(); + } + + public override async Task Execute(IJobExecutionContext context) + { + await _localEventBus.PublishAsync(new AccessLogResetArgs()); + } +} \ No newline at end of file diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs index 8420e66b..5b408bb7 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Jobs/AccessLogStoreJob.cs @@ -81,7 +81,7 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase } //删除前一天的缓存 - await RedisClient.DelAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.AddDays(-1)}"); + await RedisClient.DelAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.AddDays(-1).ToString("yyyyMMdd")}"); } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Etos/AccessLogResetArgs.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Etos/AccessLogResetArgs.cs new file mode 100644 index 00000000..8e46aa1b --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Etos/AccessLogResetArgs.cs @@ -0,0 +1,6 @@ +namespace Yi.Framework.Bbs.Domain.Shared.Etos; + +public class AccessLogResetArgs +{ + +} \ No newline at end of file