Files
Yi.Admin/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Extensions/AccessLogMiddleware.cs

91 lines
2.7 KiB
C#
Raw Normal View History

2024-08-14 18:31:37 +08:00
using FreeRedis;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
2024-08-14 12:50:28 +08:00
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
2024-08-14 12:50:28 +08:00
using Yi.Framework.Bbs.Domain.Shared.Caches;
using Yi.Framework.Bbs.Domain.Shared.Etos;
2024-08-14 12:50:28 +08:00
namespace Yi.Framework.Bbs.Application.Extensions;
/// <summary>
/// 访问日志中间件
/// 并发最高采用缓存默认10分钟才会真正操作一次数据库
/// 需考虑一致性问题,又不能上锁影响性能
/// </summary>
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<AccessLogResetArgs>,
ITransientDependency
2024-08-14 12:50:28 +08:00
{
2024-08-14 18:31:37 +08:00
/// <summary>
/// 缓存前缀
/// </summary>
private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDistributedCacheOptions>>()
.Value.KeyPrefix;
/// <summary>
/// 使用懒加载防止报错
/// </summary>
private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService<IRedisClient>();
/// <summary>
/// 属性注入
/// </summary>
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
2024-08-14 12:50:28 +08:00
2024-08-14 18:31:37 +08:00
private bool EnableRedisCache
2024-08-14 12:50:28 +08:00
{
2024-08-14 18:31:37 +08:00
get
{
var redisEnabled = LazyServiceProvider.LazyGetRequiredService<IConfiguration>()["Redis:IsEnabled"];
return redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled);
}
2024-08-14 12:50:28 +08:00
}
//该事件由job定时10秒触发
public async Task HandleEventAsync(AccessLogResetArgs eventData)
2024-08-14 12:50:28 +08:00
{
2024-08-14 18:31:37 +08:00
if (EnableRedisCache)
2024-08-14 12:50:28 +08:00
{
//分布式锁
if (await RedisClient.SetNxAsync("AccessLogLock",true,TimeSpan.FromSeconds(5)))
{
//自增长数
var incrNumber= AccessLogMiddleware.GetAccessLogNumber();
//立即重置,开始计算,方式丢失
AccessLogMiddleware.ResetAccessLogNumber();
if (incrNumber>0)
{
await RedisClient.IncrByAsync(
2024-10-18 13:14:51 +08:00
$"{CacheKeyPrefix}{AccessLogCacheConst.Key}:{DateTime.Now.Date:yyyyMMdd}", incrNumber);
}
}
2024-08-14 12:50:28 +08:00
}
}
}