iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > ASP.NET >ASP.NET Core中的响应压缩的实现
  • 849
分享到

ASP.NET Core中的响应压缩的实现

ASP.NET压缩corenetASP 2022-06-07 20:06:10 849人浏览 泡泡鱼
摘要

介绍# 响应压缩技术是目前web开发领域中比较常用的技术,在带宽资源受限的情况下,使用压缩技术是提升带宽负载的首选方案。我们熟悉的WEB服务器,比如IIS、Tomcat、Ng

介绍#

响应压缩技术是目前web开发领域中比较常用的技术,在带宽资源受限的情况下,使用压缩技术是提升带宽负载的首选方案。我们熟悉的WEB服务器,比如IIS、TomcatNginx、Apache等都可以使用压缩技术,常用的压缩类型包括Brotli、Gzip、Deflate,它们对CSSjavascripthtml、XML 和 JSON等类型的效果还是比较明显的,但是也存在一定的限制对于图片效果可能没那么好,因为图片本身就是压缩格式。其次,对于小于大约150-1000 字节的文件(具体取决于文件的内容和压缩的效率,压缩小文件的开销可能会产生比未压缩文件更大的压缩文件。在ASP.net core中我们可以使用非常简单的方式来使用响应压缩。

使用方式#

在ASP.net core中使用响应压缩的方式比较简单。首先,在ConfigureServices中添加services.AddResponseCompression注入响应压缩相关的设置,比如使用的压缩类型、压缩级别、压缩目标类型等。其次,在Configure添加app.UseResponseCompression拦截请求判断是否需要压缩,大致使用方式如下


public class Startup
{
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddResponseCompression();
  }
  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
    app.UseResponseCompression();
  }
}

如果需要自定义一些配置的话还可以手动设置压缩相关


public void ConfigureServices(IServiceCollection services)
{
  services.AddResponseCompression(options =>
  {
    //可以添加多种压缩类型,程序会根据级别自动获取最优方式
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    //添加自定义压缩策略
    options.Providers.Add<MyCompressionProvider>();
    //针对指定的MimeType来使用压缩策略
    options.MimeTypes = 
      ResponseCompressionDefaults.MimeTypes.Concat(
        new[] { "application/json" });
  });
  //针对不同的压缩类型,设置对应的压缩级别
  services.Configure<GzipCompressionProviderOptions>(options => 
  {
    //使用最快的方式进行压缩,单不一定是压缩效果最好的方式
    options.Level = CompressionLevel.Fastest;
    //不进行压缩操作
    //options.Level = CompressionLevel.NoCompression;
    //即使需要耗费很长的时间,也要使用压缩效果最好的方式
    //options.Level = CompressionLevel.Optimal;
  });
}

关于响应压缩大致的工作方式就是,当发起Http请求的时候在Request Header中添加Accept-Encoding:gzip或者其他你想要的压缩类型,可以传递多个类型。服务端接收到请求获取Accept-Encoding判断是否支持该种类型的压缩方式,如果支持则压缩输出内容相关并且设置Content-Encoding为当前使用的压缩方式一起返回。客户端得到响应之后获取Content-Encoding判断服务端是否采用了压缩技术,并根据对应的值判断使用了哪种压缩类型,然后使用对应的解压算法得到原始数据。

源码探究#

通过上面的介绍,相信大家对ResponseCompression有了一定的了解,接下来我们通过查看源码的方式了解一下它大致的工作原理。

AddResponseCompression#

首先我们来查看注入相关的代码,具体代码承载在ResponseCompressionServicesExtensions扩展类中[点击查看源码👈]


public static class ResponseCompressionServicesExtensions
{
  public static IServiceCollection AddResponseCompression(this IServiceCollection services)
  {
    services.TryAddSingleton<IResponseCompressionProvider, ResponseCompressionProvider>();
    return services;
  }
  public static IServiceCollection AddResponseCompression(this IServiceCollection services, Action<ResponseCompressionOptions> configureOptions)
  {
    services.Configure(configureOptions);
    services.TryAddSingleton<IResponseCompressionProvider, ResponseCompressionProvider>();
    return services;
  }
}

主要就是注入ResponseCompressionProvider和ResponseCompressionOptions,首先我们来看关于ResponseCompressionOptions[点击查看源码👈]


public class ResponseCompressionOptions
{
  // 设置需要压缩的类型
  public IEnumerable<string> MimeTypes { get; set; }
  // 设置不需要压缩的类型
  public IEnumerable<string> ExcludedMimeTypes { get; set; }
  // 是否开启https支持
  public bool EnableForHttps { get; set; } = false;
  // 压缩类型集合
  public CompressionProviderCollection Providers { get; } = new CompressionProviderCollection();
}

关于这个类就不做过多介绍了,比较简单。ResponseCompressionProvider是我们提供响应压缩算法的核心类,具体如何自动选用压缩算法都是由它提供的。这个类中的代码比较多,我们就不逐个方法讲解了,具体源码可自行查阅[点击查看源码👈],首先我们先看ResponseCompressionProvider的构造函数


public ResponseCompressionProvider(IServiceProvider services, IOptions<ResponseCompressionOptions> options)
{
  var responseCompressionOptions = options.Value;
  _providers = responseCompressionOptions.Providers.ToArray();
  //如果没有设置压缩类型默认采用Br和Gzip压缩算法
  if (_providers.Length == 0)
  {
    _providers = new ICompressionProvider[]
    {
      new CompressionProviderFactory(typeof(BrotliCompressionProvider)),
      new CompressionProviderFactory(typeof(GzipCompressionProvider)),
    };
  }
  //根据CompressionProviderFactory创建对应的压缩算法Provider比如GzipCompressionProvider
  for (var i = 0; i < _providers.Length; i++)
  {
    var factory = _providers[i] as CompressionProviderFactory;
    if (factory != null)
    {
      _providers[i] = factory.CreateInstance(services);
    }
  }
  //设置默认的压缩目标类型默认为text/plain、text/css、text/html、application/javascript、application/xml
  //text/xml、application/json、text/json、application/was
  var mimeTypes = responseCompressionOptions.MimeTypes;
  if (mimeTypes == null || !mimeTypes.Any())
  {
    mimeTypes = ResponseCompressionDefaults.MimeTypes;
  }
  //将默认MimeType放入HashSet
  _mimeTypes = new HashSet<string>(mimeTypes, StrinGComparer.OrdinalIgnoreCase);
  _excludedMimeTypes = new HashSet<string>(
    responseCompressionOptions.ExcludedMimeTypes ?? Enumerable.Empty<string>(),
    StringComparer.OrdinalIgnoreCase
  );
  _enableForHttps = responseCompressionOptions.EnableForHttps;
}

其中BrotliCompressionProvider、GzipCompressionProvider是具体提供压缩方法的地方,咱们就看比较常用的Gzip的Provider的大致实现[点击查看源码👈]


public class GzipCompressionProvider : ICompressionProvider
{
  public GzipCompressionProvider(IOptions<GzipCompressionProviderOptions> options)
  {
    Options = options.Value;
  }
  private GzipCompressionProviderOptions Options { get; }
  // 对应的Encoding名称
  public string EncodingName { get; } = "gzip";
  public bool SupportsFlush => true;
  // 核心代码就是这句 将原始的输出流转换为压缩的GZipStream
  // 我们设置的Level压缩级别将决定压缩的性能和质量
  public Stream CreateStream(Stream outputStream)
    => new GZipStream(outputStream, Options.Level, leaveOpen: true);
}

关于ResponseCompressionProvider其他相关的方法咱们在讲解UseResponseCompression中间件的时候在具体看用到的方法,因为这个类是响应压缩的核心类,现在提前说了,到中间件使用的地方可能会忘记了。接下来我们就看UseResponseCompression的大致实现。

UseResponseCompression#

UseResponseCompression具体也就一个无参的扩展方法,也比较简单,因为配置和工作都由注入的地方完成了,所以我们直接查看中间件里的实现,找到中间件位置ResponseCompressionMiddleware[点击查看源码👈]


public class ResponseCompressionMiddleware
{
  private readonly RequestDelegate _next;
  private readonly IResponseCompressionProvider _provider;
  public ResponseCompressionMiddleware(RequestDelegate next, IResponseCompressionProvider provider)
  {
    _next = next;
    _provider = provider;
  }
  public async Task Invoke(HttpContext context)
  {
    //判断是否包含Accept-Encoding头信息,不包含直接大喊一声"抬走下一个"
    if (!_provider.CheckRequestAcceptsCompression(context))
    {
      await _next(context);
      return;
    }
    //获取原始输出Body
    var originalBodyFeature = context.Features.Get<IHttpResponseBodyFeature>();
    var originalCompressionFeature = context.Features.Get<IHttpsCompressionFeature>();
    //初始化响应压缩Body
    var compressionBody = new ResponseCompressionBody(context, _provider, originalBodyFeature);
    //设置成压缩Body
    context.Features.Set<IHttpResponseBodyFeature>(compressionBody);
    context.Features.Set<IHttpsCompressionFeature>(compressionBody);
    try
    {
      await _next(context);
      await compressionBody.FinishCompressionAsync();
    }
    finally
    {
      //恢复原始Body
      context.Features.Set(originalBodyFeature);
      context.Features.Set(originalCompressionFeature);
    }
  }
}

这个中间件非常的简单,就是初始化了ResponseCompressionBody。看到这里你也许会好奇,并没有触发调用压缩相关的任何代码,ResponseCompressionBody也只是调用了FinishCompressionAsync都是和释放相关的,不要着急我们来看ResponseCompressionBody类的结构


internal class ResponseCompressionBody : Stream, IHttpResponseBodyFeature, IHttpsCompressionFeature
{
}

这个类实现了IHttpResponseBodyFeature,我们使用的Response.Body其实就是获取的HttpResponseBodyFeature.Stream属性。我们使用的Response.WriteAsync相关的方法,其实内部都是在调用PipeWriter进行写操作,而PipeWriter就是来自HttpResponseBodyFeature.Writer属性。可以大致概括为,输出相关的操作其核心都是在操作IHttpResponseBodyFeature。有兴趣的可以自行查阅HttpResponse相关的源码可以了解相关信息。所以我们的ResponseCompressionBody其实是重写了输出操作相关方法。也就是说,只要你调用了Response相关的Write或Body相关的,其实本质都是在操作IHttpResponseBodyFeature,由于我们开启了响应输出相关的中间件,所以会调用IHttpResponseBodyFeature的实现类ResponseCompressionBody相关的方法完成输出。和我们常规理解的还是有偏差的,一般情况下我们认为,其实只要针对输出的Stream做操作就可以了,但是响应压缩中间件竟然重写了输出相关的操作。

了解到这个之后,相信大家就没有太多疑问了。由于ResponseCompressionBody重写了输出相关的操作,代码相对也比较多,就不逐一粘贴出来了,我们只查看设计到响应压缩核心相关的代码,关于ResponseCompressionBody源码相关的细节有兴趣的可以自行查阅[点击查看源码👈],输出的本质其实都是在调用Write方法,我们就来查看一下Write方法相关的实现


public override void Write(byte[] buffer, int offset, int count)
{
  //这是核心方法有关于压缩相关的输出都在这
  OnWrite();
  //_compressionStream初始化在OnWrite方法里
  if (_compressionStream != null)
  {
    _compressionStream.Write(buffer, offset, count);
    if (_autoFlush)
    {
      _compressionStream.Flush();
    }
  }
  else
  {
    _innerStream.Write(buffer, offset, count);
  }
}

通过上面的代码我们看到OnWrite方法是核心操作,我们直接查看OnWrite方法实现


private void OnWrite()
{
  if (!_compressionChecked)
  {
    _compressionChecked = true;
    //判断是否满足执行压缩相关的逻辑
    if (_provider.ShouldCompressResponse(_context))
    {
      //匹配Vary头信息对应的值
      var varyValues = _context.Response.Headers.GetCommaSeparatedValues(HeaderNames.Vary);
      var varyByAcceptEncoding = false;
      //判断Vary的值是否为Accept-Encoding
      for (var i = 0; i < varyValues.Length; i++)
      {
        if (string.Equals(varyValues[i], HeaderNames.AcceptEncoding, StringComparison.OrdinalIgnoreCase))
        {
          varyByAcceptEncoding = true;
          break;
        }
      }
      if (!varyByAcceptEncoding)
      {
        _context.Response.Headers.Append(HeaderNames.Vary, HeaderNames.AcceptEncoding);
      }
      //获取最佳的ICompressionProvider即最佳的压缩方式
      var compressionProvider = ResolveCompressionProvider();
      if (compressionProvider != null)
      {
        //设置选定的压缩算法,放入Content-Encoding头的值里
        //客户端可以通过Content-Encoding头信息判断服务端采用的哪种压缩算法
        _context.Response.Headers.Append(HeaderNames.ContentEncoding, compressionProvider.EncodingName);
        //进行压缩时,将 Content-MD5 删除该标头,因为正文内容已更改且哈希不再有效。
        _context.Response.Headers.Remove(HeaderNames.ContentMD5); 
        //进行压缩时,将 Content-Length 删除该标头,因为在对响应进行压缩时,正文内容会发生更改。
        _context.Response.Headers.Remove(HeaderNames.ContentLength);
        //返回压缩相关输出流
        _compressionStream = compressionProvider.CreateStream(_innerStream);
      }
    }
  }
}
private ICompressionProvider ResolveCompressionProvider()
{
  if (!_providerCreated)
  {
    _providerCreated = true;
    //调用ResponseCompressionProvider的方法返回最合适的压缩算法
    _compressionProvider = _provider.GetCompressionProvider(_context);
  }
  return _compressionProvider;
}

从上面的逻辑我们可以看到,在执行压缩相关逻辑之前需要判断是否满足执行压缩相关的方法ShouldCompressResponse,这个方法是ResponseCompressionProvider里的方法,这里就不再粘贴代码了,本来就是判断逻辑我直接整理出来大致就是一下几种情况

如果请求是Https的情况下,是否设置了允许Https情况下压缩的设置,即ResponseCompressionOptions的EnableForHttps属性设置 Response.Head里不能包含Content-Range头信息 Response.Head里之前不能包含Content-Encoding头信息 Response.Head里之前必须要包含Content-Type头信息 返回的MimeType里不能包含配置的不需要压缩的类型,即ResponseCompressionOptions的ExcludedMimeTypes 返回的MimeType里需要包含配置的需要压缩的类型,即ResponseCompressionOptions的MimeTypes 如果不满足上面的两种情况,返回的MimeType里包含*/*也可以执行响应压缩

接下来我们查看ResponseCompressionProvider的GetCompressionProvider方法看它是如何确定返回哪一种压缩类型的


public virtual ICompressionProvider GetCompressionProvider(HttpContext context)
{
  var accept = context.Request.Headers[HeaderNames.AcceptEncoding];
  //判断请求头是否包含Accept-Encoding信心
  if (StringValues.IsNullOrEmpty(accept))
  {
    Debug.Assert(false, "Duplicate check failed.");
    return null;
  }
  //获取Accept-Encoding里的值,判断是否包含gzip、br、identity等,并返回匹配信息
  if (!StringWithQualityHeaderValue.TryParseList(accept, out var encodings) || !encodings.Any())
  {
    return null;
  }
  //根据请求信息和设置信息计算匹配优先级
  var candidates = new HashSet<ProviderCandidate>();
  foreach (var encoding in encodings)
  {
    var encodingName = encoding.Value;
    //Quality涉及到一个非常复杂的算法,有兴趣的可以自行查阅
    var quality = encoding.Quality.GetValueOrDefault(1);
    //quality需大于0
    if (quality < double.Epsilon)
    {
      continue;
    }
    //匹配请求头里encodingName和设置的providers压缩算法里EncodingName一致的算法
    //从这里可以看出匹配的优先级和注册providers里的顺序也有关系
    for (int i = 0; i < _providers.Length; i++)
    {
      var provider = _providers[i];
      if (StringSegment.Equals(provider.EncodingName, encodingName, StringComparison.OrdinalIgnoreCase))
      {
        candidates.Add(new ProviderCandidate(provider.EncodingName, quality, i, provider));
      }
    }
    //如果请求头里EncodingName是*的情况则在所有注册的providers里进行匹配
    if (StringSegment.Equals("*", encodingName, StringComparison.Ordinal))
    {
      for (int i = 0; i < _providers.Length; i++)
      {
        var provider = _providers[i];
        candidates.Add(new ProviderCandidate(provider.EncodingName, quality, i, provider));
      }
      break;
    }
    //如果请求头里EncodingName是identity的情况,则不对响应进行编码
    if (StringSegment.Equals("identity", encodingName, StringComparison.OrdinalIgnoreCase))
    {
      candidates.Add(new ProviderCandidate(encodingName.Value, quality, priority: int.MaxValue, provider: null));
    }
  }
  ICompressionProvider selectedProvider = null;
  //如果匹配的只有一个则直接返回
  if (candidates.Count <= 1)
  {
    selectedProvider = candidates.FirstOrDefault().Provider;
  }
  else
  {
    //如果匹配到多个则按照Quality倒序和Priority正序的负责匹配第一个
    selectedProvider = candidates
      .OrderByDescending(x => x.Quality)
      .ThenBy(x => x.Priority)
      .First().Provider;
  }
  //如果没有匹配到selectedProvider或是identity的情况直接返回null
  if (selectedProvider == null)
  {
    return null;
  }
  return selectedProvider;
}

通过以上的介绍我们可以大致了解到响应压缩的大致工作方式,简单总结一下

首先设置压缩相关的算法类型或是压缩目标的MimeType 其次我们可以设置压缩级别,这将决定压缩的质量和压缩性能 通过响应压缩中间件,我们可以获取到一个优先级最高的压缩算法进行压缩,这种情况主要是针对多种压缩类型的情况。这个压缩算法与内部机制和注册压缩算法的顺序都有一定的关系,最终会选择权重最大的返回。 响应压缩中间件的核心工作类ResponseCompressionBody通过实现IHttpResponseBodyFeature,重写输出相关的方法实现对响应的压缩,不需要我们手动进行调用相关方法,而是替换掉默认的输出方式。只要设置了响应压缩,并且请求满足响应压缩,那么有调用输出的地方默认都是执行ResponseCompressionBody里压缩相关的方法,而不是拦截具体的输出进行统一处理。至于为什么这么做,目前我还没有理解到设计者真正的考虑。

总结#

在查看相关代码之前,本来以为关于响应压缩相关的逻辑会非常的简单,看过了源码才知道是自己想的太简单了。其中和自己想法出入最大的莫过于在ResponseCompressionMiddleware中间件里,本以为是通过统一拦截输出流来进行压缩操作,没想到是对整体输出操作进行重写。因为在之前我们使用asp.net相关框架的时候是统一写Filter或者HttpModule进行处理的,所以存在思维定式。可能是Asp.Net Core设计者有更深层次的理解,可能是我理解的还不够彻底,不能够体会这样做的好处究竟是什么,如果你有更好的理解或则答案欢迎在评论区里留言解惑。

到此这篇关于ASP.net Core中的响应压缩的实现的文章就介绍到这了,更多相关ASP.NET Core 响应压缩内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文章:ASP.NET Core中预压缩静态文件的方法步骤ASP.NET Core mvc压缩样式、脚本详解详解ASP.NET Core 中间件之压缩、缓存


--结束END--

本文标题: ASP.NET Core中的响应压缩的实现

本文链接: https://www.lsjlt.com/news/30740.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用ASP.NET Core怎么实现文件响应压缩
    使用ASP.NET Core怎么实现文件响应压缩?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。误区1:未使用 Brotil 压缩  几乎不需要任何额外的代价,Br...
    99+
    2023-06-15
  • ASP.NET Core 文件响应压缩的常见使用误区
    目录误区1:未使用 Brotil 压缩误区2:使用 Fastest 级别的 Brotli 压缩误区3:使用 Optimal 级别的 Brotli 压缩误区1:未使用&nbs...
    99+
    2024-04-02
  • .Net Core HttpClient处理响应压缩详细
    目录一、使用方式二、源码探究前言:   在之前的文章ASP.NET Core中的响应压缩的实现提到,服务端的主要工作就是根据Content-Encoding头信...
    99+
    2024-04-02
  • asp.net core 中优雅的进行响应包装的实现方法
    目录摘要正常响应包装实现按需禁用包装总结摘要 在 asp.net core 中提供了 Filter 机制,可以在 Action 执行前后进行一些特定的处理,例如模型验证,响应包装等功...
    99+
    2024-04-02
  • Springboot 中的 Filter 实现超大响应 JSON 数据压缩的方法
    目录简介pom.xml 引入依赖对Response进行包装定义GzipFilter对输出进行拦截注册 GzipFilter 拦截器定义 Controller定义 Springboot...
    99+
    2022-11-13
    Springboot JSON 数据压缩 Springboot Filter
  • ASP.NET Core文件压缩常见使用误区(最佳实践)
    前言   在微软官方文档中,未明确指出文件压缩功能的使用误区。   本文将对 ASP.NET Core 文件响应压缩的常见使用误区做出说明。 误区1:未使用Brotil 压缩   几...
    99+
    2024-04-02
  • Nginx请求压缩的实现(动态压缩,静态压缩)
    目录一、介绍二、请求压缩的流程三、Gzip压缩3.1 gzip介绍3.2 gzip的使用3.3 gzip的请求3.4 静态压缩四、Brotli4.1 Brotli 概述4.2 Bro...
    99+
    2023-03-03
    Nginx 请求压缩 Nginx 压缩
  • C#实现多文件打包压缩(.Net Core)
    最近项目需要实现多文件打包的功能,尝试了一些方法,最后发现使用ICSharpCode.SharpZipLib 最符合项目的要求。 具体实现如下: 1.在 Nuget 中安装ICSha...
    99+
    2024-04-02
  • Asp.net core中依赖注入的实现
    使用服务 在Asp.net core的Controller中,可以通过如下两种方式获取系统注入的服务: 构造函数 可以直接在构造函数中传入所依赖的服务,这是非常常见的DI注入方式。 ...
    99+
    2024-04-02
  • Python3压缩和解压缩的实现方法
    这篇文章主要为大家展示了Python3压缩和解压缩的实现方法,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“Python3压缩和解压缩的实现方法”这篇文章吧。python可以做什么Python是一种...
    99+
    2023-06-06
  • ASP.NET Core中间件初始化的实现
    目录前言  自定义的方式 Use方式 基于约定的方式 实现IMiddleware的方式 源码探究 Use扩展方法 UseMiddleware 总结 前言  ...
    99+
    2024-04-02
  • .Net Core 多文件打包压缩的实现代码怎么写
    本篇文章给大家分享的是有关.Net Core 多文件打包压缩的实现代码怎么写,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。最近项目需要实现多文件打包的功能,...
    99+
    2023-06-22
  • Oracle中怎么实现表的压缩
    在Oracle中,可以通过使用表压缩功能来实现表的压缩。表压缩是一种数据压缩技术,可以减小表占用的存储空间,提高数据库性能。 表压缩...
    99+
    2024-04-19
    Oracle
  • Linux中zip压缩和unzip解压缩命令的应用
    本篇内容主要讲解“Linux中zip压缩和unzip解压缩命令的应用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux中zip压缩和unzip解压缩命令的应用”吧!把/home目录下面的m...
    99+
    2023-06-13
  • 基于Python实现文件的压缩与解压缩
    目录zip文件tar.gz文件rar文件7z文件在日常工作中,除了会涉及到使用Python处理文本文件,有时候还会涉及对压缩文件的处理。 通常会涉及到的压缩文件格式有: rar:W...
    99+
    2024-04-02
  • Redis怎么实现数据的压缩和解压缩
    Redis可以通过以下方式实现数据的压缩和解压缩: 使用Redis的压缩功能:Redis可以通过配置选项来启用对数据的压缩功能。...
    99+
    2024-05-07
    Redis
  • ASP.NET Core中间件实现限流的代码
    目录一、限流算法1.计数器算法1.1 固定窗口算法1.2 滑动窗口算法2.令牌桶算法3.漏桶算法二、ASP.NET Core中间件实现限流1.中间件代码2.在管道中的使用一、限流算法...
    99+
    2024-04-02
  • 怎么在java中利用压缩流实现压缩与解压
    本篇文章给大家分享的是有关怎么在java中利用压缩流实现压缩与解压,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程...
    99+
    2023-06-14
  • Asp.NET Core 限流控制(AspNetCoreRateLimit)的实现
    起因: 近期项目中,提供了一些调用频率较高的api接口,需要保障服务器的稳定运行;需要对提供的接口进行限流控制。避免因客户端频繁的请求导致服务器的压力。 一、AspNetCoreRa...
    99+
    2024-04-02
  • ASP.NET Core中间件初始化的实现方法
    小编给大家分享一下ASP.NET Core中间件初始化的实现方法,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!前言  在日常使用ASP.NET Core开发的过程中我们多多少少会设计到使用中间件的场景,...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作