一、环境准备(新建 .NET Web API)
先安装所有需要的 NuGet 包:
必装包
# AOP 核心
Install-Package Autofac
Install-Package Autofac.Extras.DynamicProxy
Install-Package Microsoft.Extensions.DependencyInjection
# Serilog 二选一
Install-Package Serilog
Install-Package Serilog.AspNetCore
Install-Package Serilog.Sinks.Console
Install-Package Serilog.Sinks.File
# NLog 二选一
Install-Package NLog Install-Package NLog.Web.AspNetCore # 限流 Install-Package AspNetCoreRateLimit
二、日志实现(二选一即可)
方案 1:Serilog(简洁强大)
1. Program.cs 配置
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// 配置 Serilog
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console() // 输出到控制台
.WriteTo.File("Logs/log-.txt", rollingInterval: RollingInterval.Day) // 按天切割
.CreateLogger();
builder.Host.UseSerilog(); // 替换系统默认日志
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
2. 使用日志
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
private readonly ILogger<TestController> _logger;
// 直接注入使用
public TestController(ILogger<TestController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult Get()
{
_logger.LogInformation("请求 Test 接口");
return Ok("Hello Serilog");
}
}
方案 2:NLog(配置灵活)
1. 添加 nlog.config 文件
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets>
<target xsi:type="Console" name="console"/>
<target xsi:type="File" name="file" fileName="logs/${shortdate}.log" layout="${longdate}|${level}|${message} ${exception:format=tostring}"/>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="console,file"/>
</rules>
</nlog>
2. Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseNLog(); // 使用 NLog
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
使用方式和 Serilog 完全一样,直接注入 ILogger<T> 即可。
三、AOP 切面编程(Autofac + 拦截器)
用途:自动记录方法执行日志、耗时、异常,不用每个方法手写
1. 编写 AOP 拦截器
using Castle.DynamicProxy;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
public class LogInterceptor : IInterceptor
{
private readonly ILogger<LogInterceptor> _logger;
public LogInterceptor(ILogger<LogInterceptor> logger)
{
_logger = logger;
}
public void Intercept(IInvocation invocation)
{
var method = invocation.Method;
var stopwatch = Stopwatch.StartNew();
try
{
_logger.LogInformation($"【AOP 执行】 {method.DeclaringType.Name}.{method.Name} 开始");
// 执行目标方法
invocation.Proceed();
stopwatch.Stop();
_logger.LogInformation($"【AOP 完成】 {method.Name},耗时:{stopwatch.ElapsedMilliseconds} ms");
}
catch (Exception ex)
{
_logger.LogError(ex, $"【AOP 异常】 {method.Name} 执行出错");
throw;
}
}
}
2. 注册 Autofac + AOP
using Autofac;
using Autofac.Extras.DynamicProxy;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
// Autofac 容器
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
// 注册拦截器
containerBuilder.RegisterType<LogInterceptor>();
// 注册需要 AOP 的服务(示例:TestService)
containerBuilder.RegisterType<TestService>()
.As<ITestService>()
.EnableInterfaceInterceptors() // 开启接口拦截
.InterceptedBy(typeof(LogInterceptor)); // 使用拦截器
});
builder.Services.AddControllers();
| 功能 | .NET 自带 DI | Autofac |
| 上手难度 |
⭐ 极简单 |
⭐⭐ 简单 |
| 构造函数注入 |
✅ 支持 |
✅ 支持 |
| 生命周期管理 |
✅ 基础 |
✅ 更精细 |
| 批量注册 |
❌ 不支持 |
✅ 一键批量注入 |
| 属性注入 |
❌ 不支持 |
✅ 支持 |
| AOP 切面 |
❌ 很难 |
✅ 完美支持 |
| 模块化配置 |
❌ 弱 |
✅ 强 |
| 性能 |
✅ 快 |
✅ 更快 |
3. 测试服务 + 接口
// 接口
public interface ITestService
{
void Test();
}
// 实现
public class TestService : ITestService
{
public void Test()
{
Console.WriteLine("业务方法执行");
}
}
// 控制器
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
private readonly ITestService _testService;
public TestController(ITestService testService)
{
_testService = testService;
}
[HttpGet("aop")]
public IActionResult AopTest()
{
_testService.Test();
return Ok("AOP 已生效");
}
}
访问 /test/aop 就能看到 自动日志 + 耗时统计。
四、简单限流(2 种常用方案)
方案 1:固定窗口限流(固定时间窗口限流,此外还有滑动窗口和令牌桶等)
Program.cs
using AspNetCoreRateLimit;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
// 限流配置
builder.Services.AddInMemoryRateLimiting();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
builder.Services.AddControllers();
var app = builder.Build();
// 启用限流
app.UseIpRateLimiting();
app.MapControllers();
app.Run();
添加限流规则(appsettings.json)
"IpRateLimiting": {
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1m",
"Limit": 10
}
]
}
表示:1 分钟内最多请求 10 次。
方案 2:.NET 原生限流
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
// 原生限流
builder.Services.AddRateLimiter(options =>
{
// 固定窗口:每秒最多 2 个请求
options.AddFixedWindowLimiter("fixed", opt =>
{
opt.Window = TimeSpan.FromSeconds(1);
opt.PermitLimit = 2;
});
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseRateLimiter(); // 启用限流中间件
app.MapControllers();
app.Run();
控制器使用
[HttpGet("limit")]
[EnableRateLimiting("fixed")] // 启用限流
public IActionResult LimitTest()
{
return Ok("限流测试");
}
五、三合一效果
你访问接口时,会自动:
- Serilog/NLog 记录日志(控制台 + 文件)
- AOP 拦截:记录方法执行、耗时、异常
- 限流保护:防止恶意刷接口
总结
- 日志:Serilog 最简单,NLog 更灵活,二选一即可
- AOP:Autofac 拦截器实现统一日志、异常、耗时管理
- 限流:推荐 .NET 7+ 原生限流,轻量无依赖
- 所有代码可直接复制运行,无需额外调整
来源:https://www.cnblogs.com/chuansheng/p/19913713 |