Caching در ASP.NET Core: کلید افزایش سرعت بارگذاری صفحات
چرا Caching مهم است؟
Caching فرآیند ذخیرهسازی موقت دادهها در یک مکان سریعتر (مانند حافظه) است تا در درخواستهای بعدی، نیازی به بازیابی مجدد دادهها از منبع اصلی (مانند پایگاه داده یا سرویس خارجی) نباشد. این امر منجر به مزایای متعددی میشود، از جمله:
- کاهش زمان پاسخگویی: با دسترسی به دادههای ذخیرهشده در حافظه، زمان لازم برای پردازش درخواست و تولید پاسخ به طور چشمگیری کاهش مییابد.
- کاهش بار روی منابع: با کاهش تعداد درخواستها به منابع اصلی، بار کاری آنها کاهش یافته و عملکرد کلی سیستم بهبود مییابد. این امر به ویژه در زمان اوج ترافیک بسیار مهم است.
- بهبود مقیاسپذیری: با کاهش بار روی منابع، برنامه وب میتواند تعداد بیشتری از کاربران را به طور همزمان پشتیبانی کند.
- بهبود تجربه کاربری: سرعت بارگذاری بالاتر صفحات منجر به تجربه کاربری بهتر، رضایت بیشتر و تعامل طولانیتر کاربران با وبسایت میشود.
انواع Caching در ASP.NET Core
ASP.NET Core چندین نوع Caching را برای سناریوهای مختلف ارائه میدهد:
- In-Memory Caching: این نوع Caching دادهها را در حافظه سرور وب ذخیره میکند. این سادهترین و سریعترین نوع Caching است و برای ذخیرهسازی دادههای کوچک و پرتکرار که به تغییرات فوری نیاز ندارند، مناسب است.
ASP.NET Core از رابط IMemoryCache برای مدیریت In-Memory Caching استفاده میکند.
public class HomeController : Controller
{
private readonly IMemoryCache _cache;
public HomeController(IMemoryCache cache)
{
_cache = cache;
}
public IActionResult Index()
{
if (!_cache.TryGetValue("HomePageData", out string homePageData))
{
// دادهها در Cache وجود ندارند، آنها را از منبع اصلی دریافت کنید
homePageData = GetHomePageDataFromDatabase();
// ذخیره دادهها در Cache با یک گزینه انقضا
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(30))
.SetSlidingExpiration(TimeSpan.FromSeconds(60));
_cache.Set("HomePageData", homePageData, cacheEntryOptions);
}
ViewBag.HomePageData = homePageData;
return View();
}
private string GetHomePageDataFromDatabase()
{
// منطق برای دریافت دادههای صفحه اصلی از پایگاه داده
return "Data from database at " + DateTime.Now;
}
}
در این مثال، ابتدا بررسی میشود که آیا دادههای صفحه اصلی با کلید "HomePageData" در Cache وجود دارند یا خیر. اگر وجود نداشته باشند، دادهها از پایگاه داده دریافت شده و سپس با استفاده از MemoryCacheEntryOptions در Cache ذخیره میشوند. SetAbsoluteExpiration زمان انقضای مطلق Cache را تعیین میکند و SetSlidingExpiration یک دوره عدم فعالیت را تعیین میکند که پس از آن Cache منقضی میشود.
- Distributed Caching: در برنامههای وب با چندین سرور (Web Farm یا Cloud)، In-Memory Caching به تنهایی کارآمد نیست زیرا هر سرور Cache جداگانهای دارد. Distributed Caching راه حلی برای این مشکل ارائه میدهد. در این نوع Caching، دادهها در یک حافظه مشترک بین تمام سرورها ذخیره میشوند. ASP.NET Core از طریق رابط IDistributedCache از Distributed Caching پشتیبانی میکند و پیادهسازیهای مختلفی مانند Redis و SQL Server را ارائه میدهد.
استفاده از Redis به عنوان Distributed Cache:
ابتدا بسته NuGet Microsoft.Extensions.Caching.StackExchangeRedis را به پروژه خود اضافه کنید. سپس در فایل Program.cs سرویس Redis را پیکربندی کنید:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379"; // پیکربندی اتصال به Redis
options.InstanceName = "MyAppCache"; // نام نمونه Cache (اختیاری)
});
سپس میتوانید از IDistributedCache در Controller یا سرویسهای خود استفاده کنید:
public class ProductsController : Controller
{
private readonly IDistributedCache _distributedCache;
public ProductsController(IDistributedCache distributedCache)
{
_distributedCache = distributedCache;
}
public async Task Index(int id)
{
string productJson = await _distributedCache.GetStringAsync($"product:{id}");
if (string.IsNullOrEmpty(productJson))
{
// دادهها در Cache وجود ندارند، آنها را از منبع اصلی دریافت کنید
var product = await GetProductFromDatabaseAsync(id);
// سریالیزه کردن دادهها به JSON و ذخیره در Cache
productJson = JsonSerializer.Serialize(product);
var cacheEntryOptions = new DistributedCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(60));
await _distributedCache.SetStringAsync($"product:{id}", productJson, cacheEntryOptions);
}
var cachedProduct = JsonSerializer.Deserialize(productJson);
return View(cachedProduct);
}
private async Task GetProductFromDatabaseAsync(int id)
{
// منطق برای دریافت محصول از پایگاه داده
await Task.Delay(100); // شبیهسازی تاخیر دسترسی به پایگاه داده
return new Product { Id = id, Name = $"Product {id}", Price = 19.99 };
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
در این مثال، اطلاعات مربوط به یک محصول با شناسه مشخص در Redis ذخیره و بازیابی میشود. از GetStringAsync و SetStringAsync برای کار با دادههای رشتهای (معمولاً JSON) در Distributed Cache استفاده میشود.
- Response Caching: این نوع Caching کل پاسخ HTTP (شامل وضعیت، هدرها و بدنه) را در سمت سرور ذخیره میکند. هنگامی که یک درخواست مشابه دریافت میشود، سرور میتواند پاسخ ذخیرهشده را بدون نیاز به اجرای مجدد کل Pipeline درخواست، مستقیماً ارسال کند. ASP.NET Core از Middleware ResponseCachingMiddleware برای فعالسازی Response Caching استفاده میکند و از Attribute [ResponseCache] برای پیکربندی نحوه Caching پاسخهای Actionهای Controller استفاده میشود.
ابتدا Middleware ResponseCachingMiddleware را در فایل Program.cs اضافه کنید:
builder.Services.AddResponseCaching();
// ...
app.UseResponseCaching();
سپس میتوانید از Attribute [ResponseCache] در Actionهای Controller خود استفاده کنید:
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Any, NoStore = false)]
public IActionResult Privacy()
{
return View();
}
- Duration: مدت زمان (در ثانیه) که پاسخ باید در Cache نگهداری شود.
- Location: مکانهایی که میتوان پاسخ را Cache کرد (Any: Client و Server، Client: فقط Client، None: Cache نشود).
- NoStore: تعیین میکند که آیا پاسخ نباید در هیچ Cache ذخیره شود.
نکات مهم در مورد Response Caching:
پاسخهایی که وضعیت 200 (OK) دارند به طور پیشفرض Cache میشوند.
پاسخهایی که حاوی هدرهای خاصی مانند Set-Cookie یا Authorization هستند، Cache نمیشوند.
برای سناریوهای پیچیدهتر، میتوانید از VaryByHeader، VaryByQueryKeys و VaryByCustom برای تعیین شرایط مختلف Caching استفاده کنید.
Tag Helpers و View Components Caching: ASP.NET Core امکان Cache کردن خروجی Tag Helpers و View Components را نیز فراهم میکند. این میتواند برای بهبود عملکرد بخشهای خاصی از صفحات وب که به ندرت تغییر میکنند، بسیار مفید باشد.
Cache Tag Helper:
<cache expires-after="@TimeSpan.FromMinutes(5)">
<div>
@DateTime.Now
</div>
</cache>
محتوای داخل تگ <cache> به مدت 5 دقیقه Cache میشود.
Distributed Tag Helper:
<distributed-cache id="my-distributed-cache-key" expires-after="@TimeSpan.FromHours(1)">
<div>
This content is cached in a distributed cache.
</div>
</distributed-cache>
محتوای داخل تگ <distributed-cache> در Distributed Cache ذخیره میشود.
View Component Caching:
public class MenuViewComponent : ViewComponent
{
private readonly IMemoryCache _cache;
public MenuViewComponent(IMemoryCache cache)
{
_cache = cache;
}
public IViewComponentResult Invoke()
{
if (!_cache.TryGetValue("MainMenu", out List menuItems))
{
// دریافت منوی اصلی از منبع داده
menuItems = GetMainMenuFromDatabase();
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromHours(24));
_cache.Set("MainMenu", menuItems, cacheEntryOptions);
}
return View(menuItems);
}
private List GetMainMenuFromDatabase()
{
// منطق برای دریافت منوی اصلی
return new List
{
new MenuItem { Name = "Home", Url = "/" },
new MenuItem { Name = "Products", Url = "/Products" },
new MenuItem { Name = "Contact", Url = "/Contact" }
};
}
}
در View:
@await Component.InvokeAsync("Menu")
خروجی View Component Menu به مدت 24 ساعت در In-Memory Cache ذخیره میشود.
استراتژیهای Caching مؤثر
برای استفاده بهینه از Caching و دستیابی به حداکثر عملکرد، در نظر گرفتن استراتژیهای زیر ضروری است:
- Cache کردن دادههای پرتکرار: دادههایی که به طور مکرر درخواست میشوند و به ندرت تغییر میکنند، اولویت اصلی برای Caching هستند.
- تعیین سیاستهای انقضا مناسب: انتخاب زمان انقضای مناسب برای Cache بسیار مهم است. زمان انقضای خیلی کوتاه میتواند منجر به از دست رفتن مزایای Caching شود، در حالی که زمان انقضای خیلی طولانی میتواند منجر به نمایش دادههای قدیمی به کاربران شود.
- استفاده از Cache Invalidation: هنگامی که دادههای اصلی تغییر میکنند، باید Cache مربوطه را باطل کنید تا از نمایش دادههای قدیمی جلوگیری شود. این میتواند از طریق روشهای مختلفی مانند انقضای مبتنی بر زمان، انقضای مبتنی بر رویداد یا انقضای دستی انجام شود.
- در نظر گرفتن اندازه Cache: اندازه Cache باید به اندازه کافی بزرگ باشد تا دادههای مهم را در خود جای دهد، اما نباید آنقدر بزرگ باشد که بر عملکرد سرور تأثیر منفی بگذارد.
- مانیتورینگ عملکرد Cache: نظارت بر نرخ Hit و Miss Cache به شما کمک میکند تا اثربخشی استراتژی Caching خود را ارزیابی کرده و تنظیمات لازم را انجام دهید.
- استفاده از Content Delivery Network (CDN): برای Cache کردن محتوای استاتیک مانند تصاویر، فایلهای CSS و JavaScript در سرورهای توزیعشده در سراسر جهان، استفاده از CDN میتواند به طور قابل توجهی سرعت بارگذاری صفحات را برای کاربران در مناطق مختلف جغرافیایی بهبود بخشد.
- نکات مهم در پیادهسازی Caching
- شناسایی نقاط گلوگاه: قبل از پیادهسازی Caching، نقاطی از برنامه خود را که بیشترین زمان پردازش را دارند و به طور مکرر مورد استفاده قرار میگیرند، شناسایی کنید. Caching این نقاط میتواند بیشترین تأثیر را بر عملکرد داشته باشد.
- انتخاب نوع Cache مناسب: نوع Cache مورد استفاده باید با نیازهای برنامه و نوع دادههایی که میخواهید Cache کنید، مطابقت داشته باشد.
- تست و اندازهگیری: پس از پیادهسازی Caching، عملکرد برنامه خود را به دقت تست و اندازهگیری کنید تا از بهبود واقعی عملکرد اطمینان حاصل کنید.
- پیادهسازی تدریجی: Caching را به صورت تدریجی در بخشهای مختلف برنامه خود پیادهسازی کنید و تأثیر آن را بررسی کنید.
- مستندسازی: استراتژی Caching و تنظیمات مربوطه را به طور کامل مستند کنید.
نتیجهگیری
Caching یک تکنیک قدرتمند برای بهبود عملکرد و سرعت بارگذاری صفحات وب در برنامههای ASP.NET Core است. با استفاده از انواع مختلف Caching ارائه شده توسط این فریمورک و اتخاذ استراتژیهای مؤثر، میتوانید تجربه کاربری بهتری را برای بازدیدکنندگان وبسایت خود فراهم کرده و بار روی منابع سرور خود را کاهش دهید. انتخاب نوع Cache مناسب، تعیین سیاستهای انقضا صحیح و در نظر گرفتن روشهای Cache Invalidation از جمله عوامل کلیدی در پیادهسازی موفقیتآمیز Caching در ASP.NET Core هستند. با پیادهسازی هوشمندانه Caching، میتوانید به طور قابل توجهی سرعت و مقیاسپذیری برنامههای وب خود را افزایش دهید.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.