[ASP.NET Core 3框架揭秘] 服务承载系统[1]: 承载长时间运行的服务[上篇]

2023-12-25 16:48

本文主要是介绍[ASP.NET Core 3框架揭秘] 服务承载系统[1]: 承载长时间运行的服务[上篇],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

借助.NET Core提供的承载(Hosting)系统,我们可以将任意一个或者多个长时间运行(Long-Running)的服务寄宿或者承载于托管进程中。ASP.NET Core应用仅仅是该承载系统的一种典型的服务类型而已,任何需要在后台长时间运行的操作都可以定义成标准化的服务并利用该系统来承载。

一、承载长时间运行服务

老幺网 www.laoyao.org

一个ASP.NET Core应用本质上是一个需要长时间运行的服务,开启这个服务是为了启动一个网络监听器。当监听到抵达的HTTP请求之后,该监听器会将请求传递给应用提供的管道进行处理。管道完成了对请求处理之后会生成HTTP响应,并通过监听器返回客户端。除了这种最典型的承载服务,我们还有很多其他的服务承载需求,下面通过一个简单的实例来演示如何承载一个服务来收集当前执行环境的性能指标

我们演示的承载服务会定时采集并分发当前进程的性能指标。简单起见,我们只关注处理器使用率、内存使用量和网络吞吐量这3种典型的性能指标,为此定义了下面的PerformanceMetrics类型。我们并不会实现真正的性能指标收集,所以定义静态方法Create利用随机生成的指标数据创建一个PerformanceMetrics对象。

public class PerformanceMetrics
{private static readonly Random _random = new Random();public int Processor { get; set; }public long Memory { get; set; }public long Network { get; set; }public override string ToString() => $"CPU: {Processor * 100}%; Memory: {Memory / (1024 * 1024)}M; Network: {Network / (1024 * 1024)}M/s";public static PerformanceMetrics Create() => new PerformanceMetrics{Processor = _random.Next(1, 8),Memory = _random.Next(10, 100) * 1024 * 1024,Network = _random.Next(10, 100) * 1024 * 1024};
}

承载服务通过IHostedService接口表示,该接口定义的StartAsync方法和StopAsync方法可以启动与关闭服务。我们将性能指标采集服务定义成如下这个实现了该接口的PerformanceMetricsCollector类型。在实现的StartAsync方法中,我们利用Timer创建了一个调度器,每隔5秒它会调用Create方法创建一个PerformanceMetrics对象,并将它承载的性能指标输出到控制台上。这个Timer对象会在实现的StopAsync方法中被释放。

public sealed class PerformanceMetricsCollector : IHostedService
{private IDisposable _scheduler;public Task StartAsync(CancellationToken cancellationToken){_scheduler = new Timer(Callback, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));return Task.CompletedTask;static void Callback(object state){Console.WriteLine($"[{DateTimeOffset.Now}]{PerformanceMetrics.Create()}");}}public Task StopAsync(CancellationToken cancellationToken){_scheduler?.Dispose();return Task.CompletedTask;}
}

承载系统通过IHost接口表示承载服务的宿主,该对象在应用启动过程中采用Builder模式由对应的IHostBuilder对象来创建。HostBuilder类型是对IHostBuilder接口的默认实现,所以可以采用如下方式创建一个HostBuilder对象,并调用其Build方法来提供作为宿主的IHost对象。

class Program
{static void Main(){new HostBuilder().ConfigureServices(svcs => svcs.AddSingleton<IHostedService, PerformanceMetricsCollector>()).Build().Run();}
}

在调用Build方法之前,可以调用IHostBuilder接口的ConfigureServices方法将PerformancceMetricsCollector注册成针对IHostedService接口的服务,并将生命周期模式设置成Singleton。除了采用普通的依赖服务注册方式,针对IHostedService服务的注册还可以调用IServiceCollection接口的AddHostedService<THostedService>扩展方法来完成,如下所示的编程方式与上面是完全等效的。

class Program
{static void Main(){new HostBuilder().ConfigureServices(svcs => svcs.AddHostedService<PerformanceMetricsCollector>()).Build().Run();}
}

最后调用Run方法启动通过IHost对象表示的承载服务宿主,进而启动由它承载的PerformancceMetricsCollector服务,该服务将以下图所示的形式每隔5秒显示由它“采集”的性能指标。(源代码从这里下载)

10-1

二、依赖注入

服务承载系统无缝整合了依赖注入框架。从上面给出的代码可以看出,针对承载服务的注册实际上就是将它注册到依赖注入框架中。既然承载服务实例最终是通过依赖注入框架提供的,那么它自身所依赖的服务当然也可以注册到依赖注入框架中。下面将PerformanceMetricsCollector承载的性能指标收集功能分解到由4个接口表示的服务中,其中IProcessorMetricsCollector、IMemoryMetricsCollector和INetworkMetricsCollector接口代表的服务分别用于收集3种对应性能指标,而IMetricsDeliverer接口表示的服务则负责将收集的性能指标发送出去。

public interface IProcessorMetricsCollector
{int GetUsage();
}
public interface IMemoryMetricsCollector
{long GetUsage();
}
public interface INetworkMetricsCollector
{long GetThroughput();
}public interface IMetricsDeliverer
{Task DeliverAsync(PerformanceMetrics counter);
}

我们定义的FakeMetricsCollector类型实现了3个性能指标采集接口,它们采集的性能指标直接来源于通过静态方法Create创建的PerformanceMetrics对象。FakeMetricsDeliverer类型实现了IMetricsDeliverer接口,在实现的DeliverAsync方法中,它直接将PerformanceMetrics对象承载性能指标输出到控制台上。

public class FakeMetricsCollector :IProcessorMetricsCollector,IMemoryMetricsCollector,INetworkMetricsCollector
{long INetworkMetricsCollector.GetThroughput() => PerformanceMetrics.Create().Network;int IProcessorMetricsCollector.GetUsage() => PerformanceMetrics.Create().Processor;long IMemoryMetricsCollector.GetUsage() => PerformanceMetrics.Create().Memory;
}public class FakeMetricsDeliverer : IMetricsDeliverer
{public Task DeliverAsync(PerformanceMetrics counter){Console.WriteLine($"[{DateTimeOffset.UtcNow}]{counter}");return Task.CompletedTask;}
}

由于整个性能指标的采集工作被分解到4个接口表示的服务之中,所以可以采用如下所示的方式重新定义承载服务类型PerformanceMetricsCollector。如下面的代码片段所示,可以直接在构造函数中注入4个依赖服务。对于在StartAsync方法创建的调用器来说,它会利用3个对应的服务采集3种类型的性能指标,并利用IMetricsDeliverer服务将其发送出去。

public sealed class PerformanceMetricsCollector : IHostedService
{private readonly IProcessorMetricsCollector _processorMetricsCollector;private readonly IMemoryMetricsCollector _memoryMetricsCollector;private readonly INetworkMetricsCollector _networkMetricsCollector;private readonly IMetricsDeliverer _MetricsDeliverer;private IDisposable _scheduler;public PerformanceMetricsCollector(IProcessorMetricsCollector processorMetricsCollector,IMemoryMetricsCollector memoryMetricsCollector,INetworkMetricsCollector networkMetricsCollector,IMetricsDeliverer MetricsDeliverer){_processorMetricsCollector = processorMetricsCollector;_memoryMetricsCollector     ,= memoryMetricsCollector;_networkMetricsCollector = networkMetricsCollector;_MetricsDeliverer = MetricsDeliverer;}public Task StartAsync(CancellationToken cancellationToken){_scheduler = new Timer(Callback, null, TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(5));return Task.CompletedTask;async void Callback(object state){var counter = new PerformanceMetrics{Processor = _processorMetricsCollector.GetUsage(),Memory = _memoryMetricsCollector.GetUsage(),Network = _networkMetricsCollector.GetThroughput()};await _MetricsDeliverer.DeliverAsync(counter);}}public Task StopAsync(CancellationToken cancellationToken){_scheduler?.Dispose();return Task.CompletedTask;}
}

在调用IHostBuilder接口的Build方法创建作为宿主的IHost对象之前,包括承载服务在内的所有服务都可以通过它的ConfigureServices方法进行注册,我们采用如下方式注册了作为承载服务的PerformanceMetricsCollector和它依赖的4个服务。修改后的程序启动之后同样会在控制台上看到上面图片所示的输出结果。(源代码从这里下载)

class Program
{static void Main(){var collector = new FakeMetricsCollector();new HostBuilder().ConfigureServices(svcs => svcs  .AddSingleton<IProcessorMetricsCollector>(collector).AddSingleton<IMemoryMetricsCollector>(collector).AddSingleton<INetworkMetricsCollector>(collector).AddSingleton<IMetricsDeliverer, FakeMetricsDeliverer>().AddSingleton<IHostedService, PerformanceMetricsCollector>()).Build().Run();}
}

服务承载系统[1]: 承载长时间运行的服务[上篇]
服务承载系统[2]: 承载长时间运行的服务[下篇]
服务承载系统[3]: 服务承载模型[上篇]
服务承载系统[4]: 服务承载模型[下篇]
服务承载系统[5]: 承载服务启动流程[上篇]
服务承载系统[6]: 承载服务启动流程[下篇]

这篇关于[ASP.NET Core 3框架揭秘] 服务承载系统[1]: 承载长时间运行的服务[上篇]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/536217

相关文章

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

在VSCode中本地运行DeepSeek的流程步骤

《在VSCode中本地运行DeepSeek的流程步骤》本文详细介绍了如何在本地VSCode中安装和配置Ollama和CodeGPT,以使用DeepSeek进行AI编码辅助,无需依赖云服务,需要的朋友可... 目录步骤 1:在 VSCode 中安装 Ollama 和 CodeGPT安装Ollama下载Olla

Python结合Flask框架构建一个简易的远程控制系统

《Python结合Flask框架构建一个简易的远程控制系统》这篇文章主要为大家详细介绍了如何使用Python与Flask框架构建一个简易的远程控制系统,能够远程执行操作命令(如关机、重启、锁屏等),还... 目录1.概述2.功能使用系统命令执行实时屏幕监控3. BUG修复过程1. Authorization

Linux系统之authconfig命令的使用解读

《Linux系统之authconfig命令的使用解读》authconfig是一个用于配置Linux系统身份验证和账户管理设置的命令行工具,主要用于RedHat系列的Linux发行版,它提供了一系列选项... 目录linux authconfig命令的使用基本语法常用选项示例总结Linux authconfi

Nginx配置系统服务&设置环境变量方式

《Nginx配置系统服务&设置环境变量方式》本文介绍了如何将Nginx配置为系统服务并设置环境变量,以便更方便地对Nginx进行操作,通过配置系统服务,可以使用系统命令来启动、停止或重新加载Nginx... 目录1.Nginx操作问题2.配置系统服android务3.设置环境变量总结1.Nginx操作问题

基于.NET编写工具类解决JSON乱码问题

《基于.NET编写工具类解决JSON乱码问题》在开发过程中,我们经常会遇到JSON数据处理的问题,尤其是在数据传输和解析过程中,很容易出现编码错误导致的乱码问题,下面我们就来编写一个.NET工具类来解... 目录问题背景核心原理工具类实现使用示例总结在开发过程中,我们经常会遇到jsON数据处理的问题,尤其是

SpringBoot集成图片验证码框架easy-captcha的详细过程

《SpringBoot集成图片验证码框架easy-captcha的详细过程》本文介绍了如何将Easy-Captcha框架集成到SpringBoot项目中,实现图片验证码功能,Easy-Captcha是... 目录SpringBoot集成图片验证码框架easy-captcha一、引言二、依赖三、代码1. Ea

解读docker运行时-itd参数是什么意思

《解读docker运行时-itd参数是什么意思》在Docker中,-itd参数组合用于在后台运行一个交互式容器,同时保持标准输入和分配伪终端,这种方式适合需要在后台运行容器并保持交互能力的场景... 目录docker运行时-itd参数是什么意思1. -i(或 --interactive)2. -t(或 --

Gin框架中的GET和POST表单处理的实现

《Gin框架中的GET和POST表单处理的实现》Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.For... 目录一、GET表单处理二、POST表单处理1. 使用c.PostForm获取表单字段:2. 绑定到结

pycharm远程连接服务器运行pytorch的过程详解

《pycharm远程连接服务器运行pytorch的过程详解》:本文主要介绍在Linux环境下使用Anaconda管理不同版本的Python环境,并通过PyCharm远程连接服务器来运行PyTorc... 目录linux部署pytorch背景介绍Anaconda安装Linux安装pytorch虚拟环境安装cu