[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

相关文章

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

CentOS系统Maven安装教程分享

《CentOS系统Maven安装教程分享》本文介绍了如何在CentOS系统中安装Maven,并提供了一个简单的实际应用案例,安装Maven需要先安装Java和设置环境变量,Maven可以自动管理项目的... 目录准备工作下载并安装Maven常见问题及解决方法实际应用案例总结Maven是一个流行的项目管理工具

通过prometheus监控Tomcat运行状态的操作流程

《通过prometheus监控Tomcat运行状态的操作流程》文章介绍了如何安装和配置Tomcat,并使用Prometheus和TomcatExporter来监控Tomcat的运行状态,文章详细讲解了... 目录Tomcat安装配置以及prometheus监控Tomcat一. 安装并配置tomcat1、安装

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://

解决Spring运行时报错:Consider defining a bean of type ‘xxx.xxx.xxx.Xxx‘ in your configuration

《解决Spring运行时报错:Considerdefiningabeanoftype‘xxx.xxx.xxx.Xxx‘inyourconfiguration》该文章主要讲述了在使用S... 目录问题分析解决方案总结问题Description:Parameter 0 of constructor in x

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.