狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#.NET使用客戶端緩存提高API性能

freeflydom
2025年1月11日 15:23 本文熱度 949

摘要

在現(xiàn)代應用程序中,性能始終是一個關鍵的考慮因素。無論是提高響應速度,降低延遲,還是減輕服務器負載,開發(fā)者都在尋找各種方法來優(yōu)化他們的API。在Web開發(fā)中,利用客戶端緩存是一種有效的方法,可以顯著提高API的性能。本文將結合ReplicantDelta,深入探討如何在.NET中使用客戶端緩存,巧妙地提升API的響應速度。

問題概述

盡管數(shù)據(jù)庫已經(jīng)過優(yōu)化,但在實際應用中,我們?nèi)匀粫龅揭恍┬阅芷款i。例如,當數(shù)據(jù)庫中有數(shù)百萬條記錄時,即使添加了索引,某些查詢(如對用戶名的部分匹配搜索)仍可能導致響應延遲。在API集成中,每次請求都需要花費較長的時間,這不僅影響用戶體驗,還會增加服務器的負載。

解決方案概述

為了應對這些性能挑戰(zhàn),我們可以采用以下策略:

  1. 利用客戶端緩存:通過在客戶端緩存API響應,減少重復請求,提高響應速度。
  2. 使用HTTP緩存頭:利用HTTP的緩存控制頭信息(如ETagCache-Control)來管理緩存,實現(xiàn)高效的數(shù)據(jù)更新檢測。
  3. 引入輔助庫:使用諸如ReplicantDelta這樣的庫,簡化緩存的實現(xiàn)方式,降低開發(fā)成本。

接下來,我們將詳細探討如何在.NET中實現(xiàn)上述策略,并提供具體的代碼示例。

客戶端緩存概述

什么是HTTP緩存頭?

HTTP提供了一系列頭信息,用于管理緩存行為。這些頭信息包括:

  • ETag:實體標簽,用于標識資源的版本。當資源發(fā)生變化時,ETag也會隨之更新。
  • Cache-Control:指定緩存策略,如no-cachemax-age等。
  • Last-Modified:指示資源的最后修改時間。

通過合理地設置這些頭信息,客戶端和服務器可以協(xié)同工作,實現(xiàn)高效的緩存機制。

瀏覽器中的緩存機制

當瀏覽器發(fā)送請求時,如果服務器返回了ETagLast-Modified等頭信息,瀏覽器會緩存響應。當再次請求相同資源時,瀏覽器會攜帶If-None-MatchIf-Modified-Since等條件請求頭,詢問服務器資源是否更新。如果資源未更新,服務器返回304 Not Modified,瀏覽器直接使用本地緩存的數(shù)據(jù)。

在HTTP客戶端中實現(xiàn)緩存

在非瀏覽器環(huán)境(如使用HttpClient進行API調(diào)用)中,實現(xiàn)類似的緩存機制需要額外的工作。幸運的是,Replicant庫提供了便利的解決方案。

使用Delta優(yōu)化服務器端緩存

什么是Delta?

Delta是一個開源的.NET庫,通過在數(shù)據(jù)庫中添加一個版本列(如RowVersion)或數(shù)據(jù)庫自帶的追蹤數(shù)據(jù),結合瀏覽器或客戶端的緩存機制,實現(xiàn)高效的數(shù)據(jù)更新檢測。它可以自動處理ETag的生成和驗證,簡化服務器端的開發(fā)工作。

如何使用Delta?

  1. 安裝NuGet包


    Install-Package Delta
  2. 配置中間件

    Startup.csProgram.cs中,添加Delta的中間件:


    app.UseDelta<BloggingContext>(); //Delta內(nèi)置了對EFCore的支持,只要是基于ADO.NET的ORM都可以使用Delta
  3. 修改數(shù)據(jù)庫

  • SQL Server

    在相關的數(shù)據(jù)庫表中,添加一個時間戳或版本列,用于跟蹤數(shù)據(jù)的變化。例如,使用RowVersion列:


    [Timestamp]

    public byte[] RowVersion { get; set; }
  • PostgreSQL
    啟用track_commit_timestamp功能

Delta的工作原理

響應
304 未修改
請求
根據(jù)時間戳
從 WebAssembly 和 SQL
計算當前 ETag
是否有
If-None-Match
Header?
當前
ETag與
If-None-Match匹配?
將當前 ETag
添加到響應頭
  • ETag生成:Delta會根據(jù)數(shù)據(jù)庫中的RowVersion或時間戳列,自動生成ETag
  • 條件請求:當客戶端發(fā)送請求時,攜帶If-None-Match頭信息,Delta會根據(jù)ETag判斷數(shù)據(jù)是否發(fā)生變化。
  • 響應優(yōu)化:如果數(shù)據(jù)未變化,服務器直接返回304 Not Modified,客戶端可以使用緩存的數(shù)據(jù)。

使用Delta的優(yōu)勢

  • 非侵入式:無需對現(xiàn)有的API進行大量修改,只需簡單配置即可。
  • 性能提升:在數(shù)據(jù)未變化的情況下,避免了不必要的數(shù)據(jù)庫查詢和數(shù)據(jù)傳輸。
  • 適用性強:適用于各種類型的API,包括RESTful API、GraphQL等。

使用Replicant實現(xiàn)HTTP客戶端緩存

什么是Replicant?

Replicant是由Simon Cropp開發(fā)的一個開源.NET庫,用于實現(xiàn)HTTP客戶端的緩存機制。它利用了與瀏覽器相同的HTTP緩存頭(如ETagCache-Control),可以緩存HTTP響應,避免重復請求。

使用Replicant的步驟

  1. 安裝NuGet包

    在項目中安裝Replicant包:


    Install-Package Replicant
  2. 替換HttpClient

    Replicant提供了一個包裝的HttpClient,在創(chuàng)建客戶端時使用HttpCache


    HttpCache cachedClient = HttpCache.Default;
  3. 發(fā)送請求

    使用HttpCache發(fā)送請求,與普通的HttpClient用法相同:


    var response = await httpClient.ResponseAsync("https://api.example.com/products");

    var content = await response.Content.ReadAsStringAsync();

Replicant的工作原理

  • 首次請求:當?shù)谝淮握埱竽硞€資源時,Replicant會將響應的內(nèi)容和相關的緩存頭信息(如ETag)存儲在本地緩存中。
  • 后續(xù)請求:再次請求相同資源時,Replicant會檢查本地緩存的有效性。如果緩存有效,且資源未更新,Replicant會直接返回緩存的內(nèi)容,避免實際的HTTP請求。

綜合示例:提升API集成請求性能

下面,我們將結合Replicant和Delta,提供一個完整的示例,展示如何利用客戶端和服務器端緩存,提高API的性能。

后端代碼示例

以下是使用Delta庫的后端代碼示例。該示例中,我們構建了一個簡單的博客應用,包含了博客(Blog)和帖子(Post)兩個實體。

1. 配置Program.cs


using Delta;

using Microsoft.EntityFrameworkCore;

using System.Text.Json;

using System.Text.Json.Serialization;

using TutorialClientCache.Components;



var builder = WebApplication.CreateBuilder(args);

builder.AddNpgsqlDbContext<BloggingContext>("mydb");



// 添加服務到容器

builder.Services.AddRazorComponents()

   .AddInteractiveWebAssemblyComponents();



builder.Services.AddBootstrapBlazor();



var app = builder.Build();



// 使用Delta中間件

app.UseDelta<BloggingContext>();



// 定義API端點

app.MapGet("/posts", async (string? title, BloggingContext db) =>

{

   var query = db.Posts

       .Where(p => title == null || p.Title.Contains(title))

       .OrderByDescending(p => p.Title)

       .ThenBy(p => p.Content)

       .Take(10);



   return await query.ToListAsync();

});



// 配置HTTP請求管道

if (app.Environment.IsDevelopment())

{

   app.UseWebAssemblyDebugging();

}

else

{

   app.UseExceptionHandler("/Error", createScopeForErrors: true);

}



app.UseAntiforgery();



app.MapStaticAssets();

app.MapRazorComponents<App>()

   .AddInteractiveWebAssemblyRenderMode()

   .AddAdditionalAssemblies(typeof(TutorialClientCache.Client._Imports).Assembly);



app.Run();

2. 定義數(shù)據(jù)上下文和實體

數(shù)據(jù)上下文 BloggingContext


public class BloggingContext : DbContext

{

   public BloggingContext(DbContextOptions<BloggingContext> options)

       : base(options)

   {

   }



   public DbSet<Blog> Blogs { get; set; }

   public DbSet<Post> Posts { get; set; }

}

實體類 Blog 和 Post


public class Blog

{

   public int BlogId { get; set; }

   public string Url { get; set; }



   public List<Post> Posts { get; } = new List<Post>();

}



public class Post

{

   public int PostId { get; set; }

   public string Title { get; set; }

   public string Content { get; set; }



   public int BlogId { get; set; }

   public Blog Blog { get; set; }

}

客戶端代碼示例

由于瀏覽器HttpClient已經(jīng)內(nèi)置客戶端緩存邏輯,這里提供一個可以在其他Runtime環(huán)境內(nèi)使用緩存的例子:


// See https://aka.ms/new-console-template for more information

using Replicant;

using System.Diagnostics;



Console.WriteLine("Hello, World!");



string url = "http://localhost:5225/posts?title=CSS";



//warm up

await MeasureHttpClientPerformance(url);

await MeasureHttpCachePerformance(url);



for (int i = 0; i < 5; i++)

{

   var httpClientTime = await MeasureHttpClientPerformance(url);

   Console.WriteLine($"HttpClient Time: {httpClientTime} ms");

}

for (int i = 0; i < 5; i++)

{

   var httpCacheTime = await MeasureHttpCachePerformance(url);

   Console.WriteLine($"HttpCache Time: {httpCacheTime} ms");

}





static async Task<long> MeasureHttpClientPerformance(string url)

{

   using var httpClient = new HttpClient();

   var stopwatch = Stopwatch.StartNew();



   var response = await httpClient.GetAsync(url);

   response.EnsureSuccessStatusCode();

   var content = await response.Content.ReadAsStringAsync();



   stopwatch.Stop();

   return stopwatch.ElapsedMilliseconds;

}



static async Task<long> MeasureHttpCachePerformance(string url)

{

   HttpCache cachedClient = HttpCache.Default;

   var stopwatch = Stopwatch.StartNew();



   var response = await cachedClient.ResponseAsync(url);

   response.EnsureSuccessStatusCode();

   var content = await response.Content.ReadAsStringAsync();



   stopwatch.Stop();

   return stopwatch.ElapsedMilliseconds;

}

效果



結論

通過結合使用Delta和Replicant,我們可以在.NET應用程序中有效地利用客戶端緩存機制,顯著提升API的性能。利用ETag304 Not Modified等HTTP特性,我們能夠減少不必要的網(wǎng)絡請求和數(shù)據(jù)傳輸,提高應用的響應速度和用戶體驗。

參考鏈接

?轉自https://www.cnblogs.com/madtom/p/18664378


該文章在 2025/1/11 15:23:25 編輯過
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結合碼頭的業(yè)務特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved