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;
|
2024-10-15 23:07:12 +08:00
|
|
|
|
using Volo.Abp.EventBus;
|
2024-08-14 12:50:28 +08:00
|
|
|
|
using Yi.Framework.Bbs.Domain.Shared.Caches;
|
2024-10-15 23:07:12 +08:00
|
|
|
|
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
|
2024-10-15 23:07:12 +08:00
|
|
|
|
{
|
|
|
|
|
|
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
|
|
|
|
}
|
2024-10-15 23:07:12 +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
|
|
|
|
{
|
2024-10-15 23:07:12 +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-10-15 23:07:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-14 12:50:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|