项目中有时接口访问时间过长, 但是通过浏览器 F12 查看时, 接口访问时间很正常, 所以就很奇怪, 于是写一个中间件, 记录所有接口访问时间的中间件.
一, 中间件
中间件是应用程序处理管道中的组件, 用来处理请求和响应. 如下图, 请求来之后, 第一个中间件处理, 处理完后调用下一个中间件(当然也可以选择不调用下一个中间件), 这样形成一个请求处理管道. 每一个中间件通过一个名为 RequestDelegate 的委托调用下一个中间件. 当所有的中间件处理完请求后, 再依次返回 Response.
微软提供的中间件有: Authentication(认证),Cors(跨域资源共享),Session StaticFiles(静态文件),Caching(缓存),MVC 等等.
二, 实现记录接口执行时间中间件
首先中间件不需要继承什么接口, 也没有什么限制. 我们可以仿照微软提供的中间件起名建一个 CalculateExecutionTimeMiddleware 和 CalculateExecutionTimeMiddlewareExtensions, 如果中间件中涉及配置相关的参数, 可以建一个 Option. 此中间件没有配置参数就没有 Option. 还有就是此中间件必须放在第一位, 这样才能尽可能记录请求时间.
- public class CalculateExecutionTimeMiddleware
- {
- private readonly RequestDelegate _next;// 下一个中间件
- private readonly ILogger _logger;
- Stopwatch stopwatch;
- public CalculateExecutionTimeMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
- {
- if (next == null)
- {
- throw new ArgumentNullException(nameof(next));
- }
- if (loggerFactory == null)
- {
- throw new ArgumentNullException(nameof(loggerFactory));
- }
- this._next = next;
- _logger = loggerFactory.CreateLogger<CalculateExecutionTimeMiddleware>();
- }
- public async Task Invoke(HttpContext context)
- {
- stopwatch = new Stopwatch();
- stopwatch.Start();// 在下一个中间价处理前, 启动计时器
- await _next.Invoke(context);
- stopwatch.Stop();// 所有的中间件处理完后, 停止秒表.
- _logger.LogInformation($@"接口 {context.Request.Path} 耗时{stopwatch.ElapsedMilliseconds}ms");
- }
- }
拓展方法 将中间件加入到请求处理通道中.
- public static class CalculateExecutionTimeMiddlewareExtensions
- {
- public static IApplicationBuilder UseCalculateExecutionTime(this IApplicationBuilder App)
- {
- if (App == null)
- {
- throw new ArgumentNullException(nameof(App));
- }
- return App.UseMiddleware<CalculateExecutionTimeMiddleware>();
- }
- }
使用:
- public void Configure(IApplicationBuilder App, IHostingEnvironment env, IDataProtectionProvider dataProtectionProvider)
- {
- App.UseCalculateExecutionTime();// 只需在此添加
- if (env.IsDevelopment())
- {
- App.UseDeveloperExceptionPage();
- }
- else
- {
- App.UseHsts();
- }
- App.UseHttpsRedirection();
- App.UseSession();
- App.UseMvc();
- }
三, 总结
此中间件只记录了程序处理请求的时间, 不能记录网络传输时间, 所以记录的时间比浏览器中的时间短一点, 但不影响我们找长时间相应的接口. 源码在.
来源: http://www.bubuko.com/infodetail-3073068.html