日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

Welcome to YARP - 5.压缩、缓存

發(fā)布時(shí)間:2023/11/16 windows 52 coder
生活随笔 收集整理的這篇文章主要介紹了 Welcome to YARP - 5.压缩、缓存 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

Welcome to YARP - 1.認(rèn)識(shí)YARP并搭建反向代理服務(wù)

Welcome to YARP - 2.配置功能

  • 2.1 - 配置文件(Configuration Files)
  • 2.2 - 配置提供者(Configuration Providers)
  • 2.3 - 配置過(guò)濾器(Configuration Filters)

Welcome to YARP - 3.負(fù)載均衡

Welcome to YARP - 4.限流

Welcome to YARP - 5.身份驗(yàn)證和授權(quán)

Welcome to YARP - 6.壓縮、緩存

Welcome to YARP - 7.健康檢查

Welcome to YARP - 8.分布式跟蹤

介紹

網(wǎng)關(guān)的 緩存壓縮是常見的性能優(yōu)化手段 ,用于提高系統(tǒng)的響應(yīng)速度和降低網(wǎng)絡(luò)傳輸?shù)拈_銷。

YARP 的 緩存壓縮 其實(shí)也是 .NET 本身的功能。只需要配置 .NET 本身的緩存和壓縮功能即可。

緩存

緩存的主要目的是優(yōu)化性能、提高效率,減少對(duì)后端服務(wù)的負(fù)擔(dān)。 我們可以對(duì)

頻繁請(qǐng)求的靜態(tài)數(shù)據(jù)或不經(jīng)常更改的數(shù)據(jù) 進(jìn)行 API 緩存,從而降低對(duì)后端服務(wù)的請(qǐng)求次數(shù),提高響應(yīng)速度,減輕后端服務(wù)的負(fù)載。

也可以對(duì) 靜態(tài)資源 緩存 如:css、js、圖像等,從而 加速頁(yè)面加載速度,減輕服務(wù)器壓力,提高用戶體驗(yàn)。 等等。

基于 HTTP 的響應(yīng)緩存

用于緩存的主 HTTP 標(biāo)頭是 Cache-Control,它用于指定緩存指令。 當(dāng)請(qǐng)求從客戶端到達(dá)服務(wù)器以及響應(yīng)從服務(wù)器返回客戶端時(shí),這些指令控制緩存行為。 請(qǐng)求和響應(yīng)在代理服務(wù)器之間移動(dòng),并且代理服務(wù)器還必須符合 HTTP 1.1 緩存規(guī)范。

Cache-Control 通用消息頭字段,被用于在 http 請(qǐng)求和響應(yīng)中,通過(guò)指定指令來(lái)實(shí)現(xiàn)緩存機(jī)制。緩存指令是單向的,這意味著在請(qǐng)求中設(shè)置的指令,不一定被包含在響應(yīng)中。

要使用緩存,請(qǐng)求頭中必須攜帶 Cache-Control 標(biāo)頭。同時(shí)響應(yīng)頭中也要做相應(yīng)的設(shè)置。

下表中顯示了常用 Cache-Control 指令

指令 操作
public 緩存可以存儲(chǔ)響應(yīng)。
private 響應(yīng)不得由共享緩存存儲(chǔ)。 專用緩存可以存儲(chǔ)和重用響應(yīng)。
max-age 客戶端不接受期限大于指定秒數(shù)的響應(yīng)。 示例:max-age=60(60 秒),max-age=2592000(1 個(gè)月)
no-cache 請(qǐng)求時(shí):緩存不能使用存儲(chǔ)的響應(yīng)來(lái)滿足請(qǐng)求。 源服務(wù)器重新生成客戶端的響應(yīng),中間件更新其緩存中存儲(chǔ)的響應(yīng)。 響應(yīng)時(shí):響應(yīng)不得用于未經(jīng)源服務(wù)器驗(yàn)證的后續(xù)請(qǐng)求。
no-store 請(qǐng)求時(shí):緩存不得存儲(chǔ)請(qǐng)求。 響應(yīng)時(shí):緩存不得存儲(chǔ)任何部分的響應(yīng)。

相應(yīng)的我們也要添加響應(yīng)緩存中間件:

若要測(cè)試響應(yīng)緩存,請(qǐng)使用 Fiddler、Postman 或其他可以顯式設(shè)置請(qǐng)求標(biāo)頭的工具。顯式設(shè)置上述的請(qǐng)求標(biāo)頭。

配置中間件

在 中 Program.cs ,將響應(yīng)緩存中間件服務(wù) AddResponseCaching 添加到服務(wù)集合中,并將應(yīng)用配置為將中間件與 UseResponseCaching 擴(kuò)展方法一起使用。 UseResponseCaching 將中間件添加到請(qǐng)求處理管道中:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddReverseProxy()//添加ReverseProxy相關(guān)服務(wù)到DI
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));//從配置文件中加載ReverseProxy的設(shè)置

builder.Services.AddResponseCaching(options =>
{
    options.UseCaseSensitivePaths = false; //確定是否將響應(yīng)緩存在區(qū)分大小寫的路徑上。 
    options.SizeLimit = options.SizeLimit * 10; // 響應(yīng)緩存中間件的大小限制(以字節(jié)為單位) 1G
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

// 使用 CORS 中間件時(shí),必須在 UseResponseCaching 之前調(diào)用 UseCors。
// app.UseCors();
app.UseRouting();

// 攔截請(qǐng)求并判斷 請(qǐng)求頭中是否包含 CacheControl 標(biāo)頭,如果沒有則加上緩存標(biāo)頭
app.Use(async (context, next) =>
{
    var header = context.Request.Headers;
    var cacheControl = header.CacheControl;
    if (!string.IsNullOrEmpty(header.CacheControl))
    {
        header.CacheControl = new Microsoft.Extensions.Primitives.StringValues("max-age");
    }

    await next(context);
});
app.UseResponseCaching();
app.Use(async (context, next) =>
{
    context.Response.GetTypedHeaders().CacheControl =
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(10)
        };

    context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] = new string[] { "Accept-Encoding" };

    await next(context);
});
app.MapReverseProxy();

app.MapGet("/", () => DateTime.Now.ToLongTimeString());

app.Run();

以上示例中:

  • Cache-Control:緩存可緩存響應(yīng)長(zhǎng)達(dá)10秒。
  • Vary:將中間件配置為僅當(dāng)后續(xù)請(qǐng)求的 Accept-Encoding 標(biāo)頭與原始請(qǐng)求頭匹配時(shí)才提供緩存的響應(yīng)。

app.Use(async (context, next) =>
{
var header = context.Request.Headers;
var cacheControl = header.CacheControl;
if (!string.IsNullOrEmpty(header.CacheControl))
{
header.CacheControl = new Microsoft.Extensions.Primitives.StringValues("max-age");
}

await next(context);

});

可以看到我們先設(shè)置了 請(qǐng)求頭的 緩存標(biāo)頭,如果 沒有此 設(shè)置,幾乎所有瀏覽器(標(biāo)頭值)都會(huì)發(fā)送 CacheControl:no-cache 或其他值,強(qiáng)制執(zhí)行非緩存頁(yè)面請(qǐng)求,這會(huì)導(dǎo)致 ResponseCachingMiddleware 實(shí)現(xiàn)忽略此請(qǐng)求(忽略緩存)并將其傳遞到服務(wù)器以檢索數(shù)據(jù)。 如果你用 postman 或者 fiddle則可以主動(dòng)這只CacheControl標(biāo)頭值為上述說(shuō)的那幾種。

上述示例中我們先 添加了 YARP 服務(wù),然后添加了 AddResponseCaching 響應(yīng)的緩存服務(wù),然后攔截了請(qǐng)求并設(shè)置緩存標(biāo)頭,再開啟了 UseResponseCaching() 響應(yīng)緩存中間件。接下來(lái)設(shè)置了 [響應(yīng)頭的標(biāo)頭值]( ASP.NET Core 中的響應(yīng)緩存中間件 | Microsoft Learn ),最后開啟了 代理 中間件。源碼已上傳GitHub.

壓縮

網(wǎng)絡(luò)帶寬是一種有限資源。 減小響應(yīng)大小通常可顯著提高應(yīng)用的響應(yīng)速度。 減小有效負(fù)載大小的一種方式是壓縮應(yīng)用的響應(yīng)。 但是 YARP 默認(rèn)是禁用解壓縮的,因?yàn)樗鼤?huì)增加 CPU 開銷。

什么時(shí)候使用 響應(yīng)壓縮 中間件?

在 IIS、Apache 或 Nginx 中使用基于服務(wù)器的響應(yīng)壓縮技術(shù)。

  • IIS 動(dòng)態(tài)壓縮模塊
  • Apache mod_deflate 模塊
  • Nginx 壓縮和解壓縮

而 HTTP.sys 服務(wù)器和 Kestrel 服務(wù)器當(dāng)前不提供內(nèi)置壓縮支持,這時(shí)候就需要使用響應(yīng)壓縮中間件了。

我們使用 YARP 的直接轉(zhuǎn)發(fā)來(lái) 演示一下 壓縮功能,當(dāng)然壓縮是 .NET 本身自帶的功能,你也可以通過(guò)添加壓縮中間件來(lái)開啟響應(yīng)壓縮。

代碼示例:

using System.Diagnostics;
using System.Net;
using Yarp.ReverseProxy.Forwarder;
using Yarp.ReverseProxy.Transforms;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpForwarder();

// Add services to the container.

var app = builder.Build();

// Configure our own HttpMessageInvoker for outbound calls for proxy operations
var httpClient = new HttpMessageInvoker(new SocketsHttpHandler()
{
    UseProxy = false,
    AllowAutoRedirect = false,
    AutomaticDecompression = DecompressionMethods.GZip, // 設(shè)置響應(yīng)壓縮方式
    UseCookies = false,
    ActivityHeadersPropagator = new ReverseProxyPropagator(DistributedContextPropagator.Current),
    ConnectTimeout = TimeSpan.FromSeconds(15),
});

// Setup our own request transform class
var transformer = new CustomTransformer(); // or HttpTransformer.Default;
var requestConfig = new ForwarderRequestConfig { ActivityTimeout = TimeSpan.FromSeconds(100) };

app.UseRouting();

// Configure the HTTP request pipeline.

app.MapForwarder("/{**catch-all}", "http://localhost:5047", requestConfig, transformer, httpClient);

app.Run();

/// <summary>
/// 自定義請(qǐng)求轉(zhuǎn)換
/// </summary>
class CustomTransformer : HttpTransformer
{
    ///<summary>
    /// A callback that is invoked prior to sending the proxied request. All HttpRequestMessage
    /// fields are initialized except RequestUri, which will be initialized after the
    /// callback if no value is provided. The string parameter represents the destination
    /// URI prefix that should be used when constructing the RequestUri. The headers
    /// are copied by the base implementation, excluding some protocol headers like HTTP/2
    /// pseudo headers (":authority").
    ///</summary>
    ///<param name="httpContext">傳入請(qǐng)求</param>
    ///<param name="proxyRequest">傳出的代理請(qǐng)求</param>
    ///<param name="destinationPrefix">所選目標(biāo)服務(wù)器的uri前綴,可用于創(chuàng)建RequestUri</param>
    public override async ValueTask TransformRequestAsync(HttpContext httpContext, HttpRequestMessage proxyRequest, string destinationPrefix, CancellationToken cancellationToken)
    {
        // 轉(zhuǎn)發(fā)所有頭部信息
        await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix, cancellationToken);
        // 自定義查詢query 值
        var queryContext = new QueryTransformContext(httpContext.Request);
        queryContext.Collection.Remove("param1");
        queryContext.Collection["s"] = "xx2";
        // 分配自定義 URI。在此處連接時(shí)請(qǐng)注意額外的斜杠。RequestUtilities.MakeDestinationAddress 是一個(gè)安全的默認(rèn)值。
        proxyRequest.RequestUri = RequestUtilities.MakeDestinationAddress("http://localhost:5047", httpContext.Request.Path, queryContext.QueryString);
        // 禁止原始請(qǐng)求標(biāo)頭,使用目標(biāo) Uri 中的標(biāo)頭
        proxyRequest.Headers.Host = null;
    }
}

上述示例中,我們使用了 YARP 的直接轉(zhuǎn)發(fā)模式,不需要添加 YARP 服務(wù)和中間件,但是要添加 這個(gè)東西 AddHttpForwarder,然后配置 自定義請(qǐng)求轉(zhuǎn)換 類。并開啟 壓縮模式為 GZip。

如果想看效果記得使用fiddle 抓取請(qǐng)求的返回值查看原始請(qǐng)求,因?yàn)閜ostman和瀏覽器客戶端 都會(huì)默認(rèn)對(duì)常用的壓縮格式的數(shù)據(jù)進(jìn)行解壓縮。

如果服務(wù)器本身支持壓縮,請(qǐng)使用 基于服務(wù)器的壓縮技術(shù)。而 HTTP.sys 服務(wù)器和 Kestrel 服務(wù)器 是不支持壓縮技術(shù)的,所以這時(shí)候才考慮使用 壓縮中間件。

總結(jié)

本章我們介紹了 YARP 的緩存和壓縮功能,其實(shí)也都是 .NET 自身的功能,如果了解使用過(guò) .NET的 緩存 和 壓縮 中間件很容易就能理解。本章示例代碼已上傳GitHub,建議把代碼down下來(lái)自己實(shí)驗(yàn)一下,再去配合理解。

有什么問(wèn)題歡迎留言交流。

下篇文章我們繼續(xù)介紹 YARP 的健康檢查功能。

總結(jié)

以上是生活随笔為你收集整理的Welcome to YARP - 5.压缩、缓存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。