.NET Core核心组件Hosting实践

ASP.NET Core 是一个跨平台的高性能开源框架,用于生成启用云且连接 Internet 的新式应用。ASP.NET Core应用本质上是一个服务,这个服务启动了一个网络监听器,这个监听器需要长时间的运行。当这个监听器接收到一个HTTP请求之后,监听器会将这个请求传递给管道进行处理。完成处理后就会生成相应的HTTP响应,通过这个监听器返回给客户端。那么长时间运行的服务器需要寄宿在托管服务进程中,提供功能的组件称之为Hosting,也称托管服务。

    任何在后台长时间运行的服务都可以定义标准的托管服务,寄宿在hosting,接下来我们定义一个托管服务并寄宿在hosting。

实例

    需求是我们设计一个模拟检测服务器cup,内存和硬盘使用率的服务,并寄宿在hosting,可以用配置文件appsettings.json中的属性动态控制监测时间间隔。具体看代码,大家可以把代码拷到vs试一试。

首先建一个cup,内存和硬盘使用率的接口和实现

    public class Sample    {        //首先分别建3个接口        /// <summary>        /// cpu        /// </summary>        public interface ICupCollector        {            int Get();        }
/// <summary> /// RAM(内存) /// </summary> public interface IRAMCollector { int Get(); }
/// <summary> /// IO(磁盘读写) /// </summary> public interface IIOCollector { int Get(); }
//我们实现接口,用Random模拟数字 public class Collector : ICupCollector, IRAMCollector, IIOCollector { int ICupCollector.Get() { var random = new Random(); return random.Next(0, 100); }
int IRAMCollector.Get() { var random = new Random(); return random.Next(0, 100); }
int IIOCollector.Get() { var random = new Random(); return random.Next(0, 100); } }

新建一个记录时间间隔的属性

        //新建一个记录时间间隔的属性        public class AirEnvironmentOptions        {            public long Interval { get; set; }        }

新建一个发布订阅

 public class AirEnvironmentPublisher        {            private const string Template = "CUP资源占比:{CUP, -10}" +                                             "内存资源占比:{ARM, -10}" +                                             "OI资源占比:{IO, -10}" +                                             "时间:{now}";            private readonly Action<ILogger, int, int, int, string, Exception> _logAction;            private readonly ILogger _logger;
public AirEnvironmentPublisher(ILogger<AirEnvironmentPublisher> logger) { _logger = logger; //日志发布 _logAction = LoggerMessage.Define<int, int, int, string>(LogLevel.Information, 0, Template); } //发布器进行输入 public void Publish(int cup, int arm, int io) { _logAction(_logger, cup, arm, io, DateTime.Now.ToLongTimeString(), null); } }

定义一个Hosting托管服务类

 //定义一个Hosting托管服务类        public class AirEnvironmentService : IHostedService        {            private readonly ICupCollector _cupCollector;            private readonly IRAMCollector _ramCollector;            private readonly IIOCollector _ioCollector;            private readonly AirEnvironmentPublisher _publisher;            private readonly AirEnvironmentOptions _options;
//新建一个Timer控件定时 private Timer _timer;
public AirEnvironmentService( ICupCollector CupCollector, IRAMCollector RAMCollector, IIOCollector IOCollector, AirEnvironmentPublisher publisher, IOptions<AirEnvironmentOptions> options) { _cupCollector = CupCollector; _ramCollector = RAMCollector; _ioCollector = IOCollector; _publisher = publisher; _options = options.Value; } //定时订阅开始 public Task StartAsync(CancellationToken cancellationToken) { _timer = new Timer(state => { _publisher.Publish( _cupCollector.Get(), _ramCollector.Get(), _ioCollector.Get());                }, null, 0, _options.Interval); return Task.CompletedTask; } //停止 public Task StopAsync(CancellationToken cancellationToken) { _timer?.Dispose(); return Task.CompletedTask; } }

把托管服务类加入到Hosting

  public static void Start()        {            var collector = new Collector();//方法实现            var host = new HostBuilder()//新建一个Hosting                //读取配置文件                .ConfigureAppConfiguration((context, builder) => builder.AddJsonFile("appsettings.json"))                .ConfigureServices((context, collection) => collection                    .AddSingleton<ICupCollector>(collector)//单例注入Cup                    .AddSingleton<IRAMCollector>(collector)//单例注入RAM                    .AddSingleton<IIOCollector>(collector)//单例注入IO                    .AddSingleton<AirEnvironmentPublisher>()//单例发布订阅                    .AddHostedService<AirEnvironmentService>()//把托管服务类加入到Hosting                    .AddOptions()                    .Configure<AirEnvironmentOptions>(                        context.Configuration.GetSection("AirEnvironment"))//把配置文件的时间间隔读取                )                //添加日志                .ConfigureLogging((context, builder) => builder                    .AddConfiguration(context.Configuration.GetSection("Logging"))                    .AddConsole())                .Build();            //运行            host.Run();        }

在配置文件中加入间隔时间和日志等级

 

 

 

按f5尝试一下,完美。如下图

 

 

 

 

鸣谢:

https://mp.weixin.qq.com/s/gky1O_RyqFqKV58LLi-fHw

posted @ 2022-07-05 00:20  春光牛牛  阅读(248)  评论(0编辑  收藏  举报