Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 16824|Răspunde: 0

[ASP.NET] Construiește un cache de fișiere personalizat ASP.NET optimizarea performanței

[Copiază linkul]
Postat pe 19.04.2015 22:06:12 | | | |
ASP.NET cache de ieșire (adică HTML static) era bazată pe memorie până la .NET 4.0. Asta înseamnă că, dacă site-ul nostru conține mult cache, este ușor să consumi memorie locală. Acum, cu ajutorul lui . OutputCacheProvider în .NET 4.0, avem mai multe opțiuni pentru a crea propriul nostru cache. De exemplu, putem stoca cache-ul de ieșire HTML într-un server cluster distribuit cu memcaching sau într-un MongoDB (o bază de date orientată pe documente folosită frecvent, citiți acest http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx). Desigur, putem stoca și cache-ul ca fișier pe hard disk, ceea ce este cea mai ieftină metodă având în vedere scalabilitatea, iar acest articol este despre cum să construiești un cache de fișiere personalizat.
1:OutputCacheProvider
OutputCacheProvider este o clasă de bază abstractă pe care trebuie să o suprascriem pentru patru dintre metodele sale, care sunt:
Adaugă metoda pentru a introduce elementul specificat în cache-ul de ieșire.
Get, care returnează o referință la elementul specificat din cache-ul de ieșire.
Metoda de eliminare pentru a elimina elementul specificat din cache-ul de ieșire.
set, introduce elementul specificat în cache-ul de ieșire și suprascrie elementul dacă este stocat în cache.
2: Creează-ți propria clasă de gestionare a cache-ului fișierelor
Tipul este FileCacheProvider, iar codul este următorul:

  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. }
Cod de copiere
Există două locuri care necesită atenție specială:
În metoda Adunării, există o judecată condiționată care trebuie gestionată în acest mod, altfel mecanismul de cache va stoca primul rezultat, iar cache-ul va expira după data expirării și nu va fi reconstruit.
În programul exemplu, pur și simplu punem cache-ul în directorul cache, iar în practica reală a proiectului, având în vedere că paginile stocate în cache vor fi mii, trebuie să facem clasificarea directoarelor, altfel găsirea și citirea fișierelor cache va deveni un blocaj de eficiență, ceea ce va consuma CPU-ul.
3: Fișier de configurare

Trebuie să configurăm în Web.config ca handler-ul de cache să fie un FileCacheProvider personalizat, adică să adăugăm un nod sub 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>
Cod de copiere

4: Utilizarea cache-ului

Presupunem că folosindu-l sub controlul MVC (dacă vrei să-l folosești pe o pagină de ASP.NET, include <% în page@OutputCache VaryByParam="none" Duration="10" %>), și poți vedea că Index nu este stocat în cache de ieșire, în timp ce Index2 este stocat în cache timp de 10 secunde.
  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. }
Cod de copiere
5: Verifică efectul
Codul de mai sus, după ce accesează Index2, va genera un fișier cache în folderul Cache, după cum urmează:

Acum, să evaluăm comparația de performanță dintre cache-ul de ieșire și cache-ul de ieșire, simulând 100 de cereri concurente de la 100 de utilizatori după cum urmează:








Precedent:Ciclul de viață al sesiunii
Următor:C#. .NET pentru a preveni atacurile de injecție SQL
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com