Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 16824|Відповідь: 0

[ASP.NET] Створіть власний кеш файлів ASP.NET оптимізації продуктивності

[Копіювати посилання]
Опубліковано 19.04.2015 22:06:12 | | | |
ASP.NET кешування вихідних даних (тобто статичний HTML) базувалося на пам'яті до версії .NET 4.0. Це означає, що якщо наш сайт містить багато кешу, локальну пам'ять легко споживати. Тепер, за допомогою . OutputCacheProvider у .NET 4.0 у нас є кілька варіантів створення власного кешу. Наприклад, ми можемо зберігати кеш виводу HTML у розподіленому кластерному сервері memcached або MongoDB (поширена документно-орієнтована база даних, читайте http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx). Звісно, ми також можемо зберігати кеш у вигляді файлу на жорсткому диску, що є найдешевшим способом з огляду на масштабованість, а ця стаття про те, як створити власний кеш файлів.
1:OutputCacheProvider
OutputCacheProvider — це абстрактний базовий клас, який потрібно перевизначити чотири його методи, а саме:
Додайте метод для вставки заданого елемента у кеш виводу.
Get method, який повертає посилання на вказаний елемент у вихідному кеші.
Метод видалення для видалення вказаного елемента з кешу виходу.
Встановіть метод, вставляйте вказаний елемент у кеш виводу і перезаписують його, якщо він кешований.
2: Створіть власний клас обробки кешування файлів
Тип — FileCacheProvider, а код такий:

  1. public class FileCacheProvider : OutputCacheProvider
  2. {
  3.     private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

  4.     public override void Initialize(string name, NameValueCollection attributes)
  5.     {
  6.         base.Initialize(name, attributes);
  7.         CachePath = HttpContext.Current.Server.MapPath(attributes["cachePath"]);
  8.     }

  9.     public override object Add(string key, object entry, DateTime utcExpiry)
  10.     {
  11.         Object obj = Get(key);
  12.         if (obj != null)    //这一步很重要
  13.         {
  14.             return obj;
  15.         }
  16.         Set(key,entry,utcExpiry);
  17.         return entry;
  18.     }

  19.     public override object Get(string key)
  20.     {
  21.         string path = ConvertKeyToPath(key);
  22.         if (!File.Exists(path))
  23.         {
  24.             return null;
  25.         }
  26.         CacheItem item = null;
  27.         using (FileStream file = File.OpenRead(path))
  28.         {
  29.             var formatter = new BinaryFormatter();
  30.             item = (CacheItem)formatter.Deserialize(file);
  31.         }

  32.         if (item.ExpiryDate <= DateTime.Now.ToUniversalTime())
  33.         {
  34.             log.Info(item.ExpiryDate + "*" + key);
  35.             Remove(key);
  36.             return null;
  37.         }
  38.         return item.Item;
  39.     }


  40.     public override void Set(string key, object entry, DateTime utcExpiry)
  41.     {
  42.         CacheItem item = new CacheItem(entry, utcExpiry);
  43.         string path = ConvertKeyToPath(key);
  44.         using (FileStream file = File.OpenWrite(path))
  45.         {
  46.             BinaryFormatter formatter = new BinaryFormatter();
  47.             formatter.Serialize(file, item);
  48.         }
  49.     }
  50.       
  51.     public override void Remove(string key)
  52.     {
  53.         string path = ConvertKeyToPath(key);
  54.         if (File.Exists(path))
  55.             File.Delete(path);
  56.     }

  57.     public string CachePath
  58.     {
  59.         get;
  60.         set;
  61.     }

  62.     private string ConvertKeyToPath(string key)
  63.     {
  64.         string file = key.Replace('/', '-');
  65.         file += ".txt";
  66.         return Path.Combine(CachePath, file);
  67.     }
  68. }

  69. [Serializable]
  70. public class CacheItem
  71. {
  72.     public DateTime ExpiryDate;
  73.     public object Item;

  74.     public CacheItem(object entry, DateTime utcExpiry)
  75.     {
  76.         Item = entry;
  77.         ExpiryDate = utcExpiry;
  78.     }
  79. }
Копія коду
Є два місця, які потребують особливої уваги:
У методі Add існує умовне судження, яке має оброблятися таким чином, інакше механізм кешування кешує перший результат, і кеш закінчиться після дати закінчення і не буде відновлений.
У прикладі програми ми просто кладемо кеш у каталог кешу, і на практиці проєкту, враховуючи, що кешованих сторінок буде тисячі, потрібно класифікувати каталоги, інакше пошук і читання кеш-файлів стане вузьким місцем ефективності, що виснажує процесор.
3: Конфігураційний файл

Нам потрібно налаштувати у Web.config так, щоб обробник кешу був власним FileCacheProvider, тобто додати вузол у FileCacheProvider:
  1. <caching>
  2.   <outputCache defaultProvider="FileCache">
  3.     <providers>
  4.       <add name="FileCache" type="MvcApplication2.Common.FileCacheProvider" cachePath="~/Cache" />
  5.     </providers>
  6.   </outputCache>
  7. </caching>
Копія коду

4: Використання кешу

Ми припускаємо, що при використанні його в керуванні MVC (якщо хочете використовувати на сторінці ASP.NET, додайте <% у page@OutputCache VaryByParam="none" Duration="10" %>), і ви побачите, що Index не кешується на виході, а Index2 кешується на 10 секунд.
  1. public class HomeController : Controller
  2. {
  3.     private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  4.     static string s_conn = "Data Source=192.168.0.77;Initial Catalog=luminjidb;User Id=sa;Password=sa;";
  5.     public ActionResult Index()
  6.     {
  7.         using (DataSet ds = Common.SqlHelper.ExecuteDataset(s_conn, CommandType.Text, "select top 1* from NameTb a, DepTb b where a.DepID = b.ID ORDER BY NEWID()"))
  8.         {
  9.             ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
  10.         }
  11.         return View();
  12.     }

  13.     [OutputCache(Duration = 10, VaryByParam = "none")]
  14.     public ActionResult Index2()
  15.     {
  16.         using (DataSet ds = Common.SqlHelper.ExecuteDataset(s_conn, CommandType.Text, "select top 1* from NameTb a, DepTb b where a.DepID = b.ID ORDER BY NEWID()"))
  17.         {
  18.             ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
  19.         }
  20.         return View();
  21.     }
  22. }
Копія коду
5: Перевірте ефект
Вищенаведений код після доступу до Index2 згенерує кеш-файл у папці Cache, наступним чином:

Тепер оцінимо порівняння продуктивності між кешом виводу та кешом, імітуючи 100 одночасних запитів від 100 користувачів наступним чином:








Попередній:Життєвий цикл сесії
Наступний:C#. .NET для запобігання атакам SQL-ін'єкцій
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com