改善我的.NET 6应用程序的性能
#spanish #redis #csharp #latam

在这篇文章中,我们将重点介绍用于优化某些特定服务响应的缓存情况。

为此,我将解释我的GitHub CacheServicesApp存储库中的以下代码,其中它在带有REDIS的.NET 6 API中实现

预先要求

  • 第一件事是安装了redis,为此,我有一篇文章,我在其中解释了如何在docker中安装redis Redis en Docker Container
  • 安装了Visual Studio 2022

问题

以下问题是假设的,可以在真实的生产环境中发生:

我们有一个安装在美国云中的API,必须与智利的另一个外部服务进行通信。问题在于,由于服务和对应用的高需求之间的地理差异,它具有很高的延迟,这会影响响应时间。

解决方案

可能的解决方案是设置与此服务相同位置的分布式缓存服务器(在这种情况下 redis )。

为什么缓存分布式而不是在内存的缓存中:这将取决于我们需要提取的数据,在这种情况下,另一个客户端也消耗了我们需要提取的数据,这将是使用分布式缓存的一个不错的选择。

建立服务

创建解决方案

  • 在Visual Studio 2022中,我们使用 ASP Net创建一个项目。核心Web API

  • 然后,您将请求该项目的名称,该项目将为 cacseviceapp

  • 在下一步中,我们选择

    • 框架: .net 6.0
    • 检查配置https
    • 使用控制器的标记检查
    • 标记检查启用与OpenOpi 的兼容性(实现Swagger)
  • 使用此步骤,我们已经拥有我们的项目和列表列表

Image description

创建项目

现在,我们必须在项目中添加两层,这将是类型的库。

Image description

现在我们拥有:我们实体的模型层,连接到外部源的服务层以及我们的演示层,在这种情况下是API类型。

安装掘金软件包

要连接到redis,我们必须安装以下软件包

在我们的 cacseviceapp.Services lay

microsoft.extensions.caching.abstractions

这个pawall是la Interfaz的后者 iDistributedCache 将使我们能够与 redis 进行互动,但我们会看到Adelante。

在我们公开API cacseviceapp 的层中,我们安装了包装:

microsoft.extensions.caching.stackexchange

这将使我们在 program.cs 中注入连接链 redis。

连接到服务

cacheserviceapp

上几点中提到的第一个,我们必须在 cacseviceapp演示中生成连接。

appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Caching": {
    "RedisConnection": "localhost:6379"
  },
  "Endpoint": {
    "UrlBirds": "https://aves.ninjas.cl/api/birds"
  }
}

  • redisconnection 是我们与redis的连接链。请记住,在此示例中,我们在Docker中使用Redis,该教程将其留在上面的链接中。

  • 端点所有权p>

program.cs:

using CacheServiceApp.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var configuration = builder.Configuration;
builder.Services.AddControllers();

builder.Services.AddHttpClient<IBirdsService, BirdsService>(client =>
{
    client.BaseAddress = new Uri(configuration.GetValue<string>("Endpoint:UrlBirds"));
});

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = configuration.GetValue<string>("Caching:RedisConnection");
});

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseAuthorization();

app.MapControllers();

app.Run();

  • ACA在课堂上是重要的三点:
  1. 我获得配置,以带来appsettings.json连接的刺痛
var configuration = builder.Configuration;
  1. Geno注入我们消耗的服务的HTTPCLEINT
builder.Services.AddHttpClient<IBirdsService, BirdsService>(client =>
{
    client.BaseAddress = new Uri(configuration.GetValue<string>("Endpoint:UrlBirds"));
});
    <>conxisión到redis
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = configuration.GetValue<string>("Caching:RedisConnection");
});

Cacheserviceapp.Services

要连接到服务,您必须创建Birdservice类和Ibird服务接口,然后执行依赖项注入。

birdservice.cs:

public class BirdsService : IBirdsService
{
    private readonly HttpClient _httpClient;
    private readonly IDistributedCache _cache;

    public BirdsService(HttpClient httpClient, IDistributedCache cache) => (_httpClient, _cache) = (httpClient, cache);

    public async Task<List<Bird>> Get()
    {
        string cacheKey = "listBirds";
        string serializedBirds;

        var redisBirds = await _cache.GetAsync(cacheKey);
        List<Bird> listBirds;

        if (redisBirds != null)
        {
            serializedBirds = Encoding.UTF8.GetString(redisBirds);
            listBirds = JsonConvert.DeserializeObject<List<Bird>>(serializedBirds);
        }
        else
        {
            listBirds = await _httpClient.GetFromJsonAsync<List<Bird>>(_httpClient.BaseAddress);
            serializedBirds = JsonConvert.SerializeObject(listBirds);
            redisBirds = Encoding.UTF8.GetBytes(serializedBirds);
            var options = new DistributedCacheEntryOptions()
                .SetAbsoluteExpiration(TimeSpan.FromSeconds(30))
                .SetSlidingExpiration(TimeSpan.FromSeconds(10));

            await _cache.SetAsync(cacheKey, redisBirds, options);
        }

        return listBirds;
    }
}
  • ACA在课堂上很重要:
  1. 声明接口IDistributedCache将在Redis中获取和Gurdar数据
private readonly HttpClient _httpClient;
private readonly IDistributedCache _cache;

public BirdsService(HttpClient httpClient, IDistributedCache cache)
  1. 从Redis获取数据
var redisBirds = await _cache.GetAsync(cacheKey);
  1. 将数据存储在Redis中
var options = new DistributedCacheEntryOptions()
                .SetAbsoluteExpiration(TimeSpan.FromSeconds(30))
                .SetSlidingExpiration(TimeSpan.FromSeconds(10));

await _cache.SetAsync(cacheKey, redisBirds, options);

随着Birdservice.cs的实现,我们将进行以下操作:

  1. 我们验证了redis中是否有关键listbirds中的数据
  2. 如果有数据,则可以为字节的排列,然后从JSON的对象
  3. 如果第一次在La Cache中没有数据,请咨询鸟类服务
  4. 在JSON中序列化,然后将它们作为重复的字节安排,绝对到期30秒,部分到期10秒,这将说,如果没有人在10秒内咨询,则最多30秒就会到期。

让我们尝试解决方案

我们运行我们的cacseviceapp应用程序并向我们展示招摇。

要尝试它,我将使用邮递员,对于我的情况,API使用端口5112:

Image description

我们第一次执行服务延迟9.73秒

Image description

第二次我们执行它,我将寻找redis,因此通过降至18毫秒的响应速度将具有更高的响应速度。

Image description

结论

  • 在9秒至18毫秒之间的示例中,没有太大的差异,但是如果他们在服务的生产环境中实施了大约10秒和30秒的生产环境,并且每分钟有数百个申请看到差异。

  • 每次我们需要提高性能时,您都必须评估是否有必要

1 in211⁄4 Mi Portafolio