使用.NetCore自带的后台作业,出入队简单模拟生产者消费者处理请求响应的数据

博客 分享
0 230
优雅殿下
优雅殿下 2022-06-28 18:01:06
悬赏:0 积分 收藏

使用.NetCore自带的后台作业,出入队简单模拟生产者消费者处理请求响应的数据

环境:Core:3.1的项目

说明:由于该方案为个人测试项目,重启时队列中的部分数据很可能会丢失,

对数据有要求的该方案不适用,不能照搬需要持久化处理,

另外发布到Linux Docker中通常不会自动回收,但是发布到IIS中需要简单设置不回收即可!!! 如下截图:

在IIS中找到这个站点所用的程序池,点击 高级设置。。。 

回收——固定时间间隔       修改为 0

回收——虚拟/专用内存限制   修改为 0

进程模型——闲置超时       修改为 0

1:先来看效果

1.1:操作日志数据到表

 1.2:操作日志数据到文件

 2:过滤器

using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Mvc.Filters;using System.Text;using System.Diagnostics;using QzjcService.Models.Dto.LogModels;using QzjcService.Controllers;using SqlSugar.IOC;using Microsoft.Extensions.Logging;using Newtonsoft.Json;using QzjcService.Helper;using Microsoft.AspNetCore.Mvc;using QzjcService.Models;namespace QzjcService.Filters{    public class ActionNewLogFilter : ActionFilterAttribute    {        private static Stopwatch _watting = new Stopwatch();        public static double? longtime = 0;        private ActionLogModel log = new ActionLogModel();        private readonly ILogger<ActionNewLogFilter> _logger;        public ActionNewLogFilter(ILogger<ActionNewLogFilter> logger)        {            _logger = logger;        }        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)        {            _watting.Start();            string controllerName = context.ActionDescriptor.RouteValues["controller"];            string actionName = context.ActionDescriptor.RouteValues["action"];            string method = context.HttpContext.Request.Method;//请求方式            string queryString = context.HttpContext.Request.QueryString.Value;//地址参数            string argments = JsonConvert.SerializeObject(context.ActionArguments);            string url = context.HttpContext.Request.Host + context.HttpContext.Request.Path;//接口地址            var logStr = string.Format("\r\n【接口地址】:{0} \r\n【请求方式】:{1} \r\n【地址参数】:{2} \r\n【Body参数】:{3}", new object[] { url, method, queryString, argments });            log.ControllerName = controllerName;            log.ActionName = actionName;        //请求方式 0:get, 1:Post            log.Menthod = (method.Equals("get", StringComparison.InvariantCultureIgnoreCase) || method.Equals("httpget", StringComparison.InvariantCultureIgnoreCase)) ? 0 : 1;            log.CreateTime = DateTime.Now;            log.RequstParms = logStr;            var _context = context.HttpContext;            if (_context != null)            {                var tokenStr = context.HttpContext.Request.Headers[ConstData.Authorization].ToString();                log.userId = string.IsNullOrEmpty(tokenStr) ? 0 : TokenHelper.GetUserModel(context.HttpContext)?.UserId;            }            await base.OnActionExecutionAsync(context, next);        }        public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)        {            _watting.Stop();            longtime = 0;            if (context.Result is ObjectResult result)            {                if (result != null)                    log.ResposeParam = JsonConvert.SerializeObject(result.Value);            }            longtime = _watting.Elapsed.TotalMilliseconds;            log.LongTimeMs = longtime.Value;            _watting.Reset();            log.RequstParms += "\r\n【响应参数】:" + log.ResposeParam + "\r\n============================================";            _logger.LogCritical(log.RequstParms);            //  await DbScoped.Sugar.Insertable<ActionLogModel>(log).ExecuteCommandAsync();            await LogQueueHelper.EnQueueLogAsync(log);            await base.OnResultExecutionAsync(context, next);        }    }}

3:后台自带的定时器

using Microsoft.Extensions.Hosting;using Microsoft.Extensions.Logging;using QzjcService.Helper;using QzjcService.Models.Dto.LogModels;using SqlSugar.IOC;using System;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;namespace QzjcService.Services{    public class LogTimeService : BackgroundService    {        private readonly ILogger<LogTimeService> _logger;        public LogTimeService(ILogger<LogTimeService> logger )        {            _logger = logger;        }        protected override async Task ExecuteAsync(CancellationToken stoppingToken)        {            await Task.Factory.StartNew(async () =>            {                while (!stoppingToken.IsCancellationRequested)                {                    try                    {                        var model = await LogQueueHelper.DeQueueLogAsync();                        if (model != null)                        {                            Console.WriteLine($"===={DateTime.Now}=LogTimeService=DeQueueLog  Success====");                            await DbScoped.Sugar.Insertable<ActionLogModel>(model).ExecuteCommandAsync();                        }                        await Task.Delay(3000);                    }                    catch (Exception ex)                    {                        _logger.LogError($"====={DateTime.Now}===LogTimeService异常:=={ex.Message}==========");                        continue;                    }                }            });        }    }}

4:Log记录Model

using SqlSugar;using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations.Schema;using System.Linq;using System.Threading.Tasks;namespace QzjcService.Models.Dto.LogModels{    [Table("qzjc_action_loginfos")]    [SugarTable("qzjc_action_loginfos")]    public class ActionLogModel    {        /// <summary>        ///         /// </summary>        [Column("id")]        [SugarColumn(ColumnName = "id")]        public int id { get; set; }        /// <summary>        ///         /// </summary>        [Column("controller_name")]        [SugarColumn(ColumnName = "controller_name")]        public string ControllerName { get; set; }        /// <summary>        ///         /// </summary>        [Column("action_name")]        [SugarColumn(ColumnName = "action_name")]        public string ActionName { get; set; }        /// <summary>        ///         /// </summary>        [Column("request_parms")]        [SugarColumn(ColumnName = "request_parms")]        public string RequstParms { get; set; }        /// <summary>        ///         /// </summary>        [Column("long_time")]        [SugarColumn(ColumnName = "long_time")]        public double LongTimeMs { get; set; }        /// <summary>        ///         /// </summary>        [Column("create_time")]        [SugarColumn(ColumnName = "create_time")]        public DateTime CreateTime { get; set; }        /// <summary>        ///         /// </summary>        [Column("create_userid")]        [SugarColumn(ColumnName = "create_userid")]        public int? userId { get; set; }        [Column("menthod")]        [SugarColumn(ColumnName ="")]        public int? Menthod { get; set; }        //[Column("state")]        //[SugarColumn(ColumnName = "state")]        //public int? State { get; set; }                [Column("respose_parms")]        [SugarColumn(ColumnName = "respose_parms")]        public string ResposeParam { get; set; }    }}

5:贴上系统自带的队列Queue

using QzjcService.Models.Dto.LogModels;using System.Collections;using System.Threading.Channels;using System.Threading.Tasks;namespace QzjcService.Helper{    public static class LogQueueHelper    {        public static Queue queue;        private static readonly object Lock = new object();        static LogQueueHelper()        {            queue = new Queue();        }        /// <summary>        ///         /// </summary>        /// <returns></returns>        private static async Task<Queue> GetQueueAsync()        {            if (queue == null)            {                lock (Lock)                {                    if (queue == null)                        queue = new Queue();                }            }            await Task.CompletedTask;            return queue;        }        public static async Task<bool> EnQueueLogAsync(ActionLogModel model)        {            try            {                queue = await GetQueueAsync();                queue.Enqueue(model);                return true;            }            catch (System.Exception)            {                return false;            }        }        public static async Task<ActionLogModel> DeQueueLogAsync()        {            try            {                queue = await GetQueueAsync();                object obj = queue.Dequeue();                if (obj != null)                {                    ActionLogModel model = obj as ActionLogModel;                    return model ?? null;                }                return null;            }            catch (System.Exception)            {                return null;            }        }    }}

6:这里也贴出Serilog相关code

using System;using System.IO;using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Hosting;using Microsoft.Extensions.Logging;using Microsoft.Extensions.Configuration;using Serilog;using Serilog.Events;namespace QzjcService{    public class Program    {        public static void Main(string[] args)        {            string dataTime = DateTime.Now.ToString("yyyy-MM-dd");//这里去掉更好,让其自增长            string fileStr = $"Logs/{dataTime}_logs.txt";            Log.Logger = new LoggerConfiguration()                .MinimumLevel.Warning() //Debug()                  .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)                  .MinimumLevel.Override("System", LogEventLevel.Warning)                  .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)                  .Enrich.FromLogContext()                  .WriteTo.Async(c => c.File(fileStr, rollOnFileSizeLimit: true, fileSizeLimitBytes: 1024 * 1024 * 10, retainedFileCountLimit: 30))                  .CreateLogger();            try            {                Log.Information("=========Starting web host==========");                CreateHostBuilder(args).Build().Run();            }            catch (Exception ex)            {                Log.Fatal(ex, "Host terminated unexpectedly!");            }            finally            {                Log.CloseAndFlush();            }        }        public static IHostBuilder CreateHostBuilder(string[] args) =>            Host.CreateDefaultBuilder(args)             .ConfigureLogging((hostingContext, builder) =>             {                 builder.ClearProviders();             })                .ConfigureWebHostDefaults(webBuilder =>                {                    webBuilder.ConfigureKestrel(c => { c.Limits.MaxRequestBodySize = 1024 * 1024 * 300; });                    webBuilder.UseUrls("http://*:4444");                    webBuilder.UseStartup<Startup>();                })               .UseSerilog();    }}
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="8.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />

posted @ 2022-06-28 17:31 天天向上518 阅读(70) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员