Este artículo es un artículo espejo de traducción automática, por favor haga clic aquí para saltar al artículo original.

Vista: 16824|Respuesta: 0

[ASP.NET] Construir una caché de archivos personalizada ASP.NET optimización del rendimiento

[Copiar enlace]
Publicado en 19/4/2015 22:06:12 | | | |
ASP.NET caché de salida (es decir, HTML estático) se basaba en memoria hasta .NET 4.0. Esto significa que si nuestro sitio contiene mucha caché, es fácil consumir memoria local. Ahora, con la ayuda de . En OutputCacheProvider en .NET 4.0, tenemos varias opciones para crear nuestra propia caché. Por ejemplo, podemos almacenar la caché de salida HTML en un servidor de clúster distribuido con memcaching o en MongoDB (una base de datos orientada a documentos de uso común, lee esto http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx). Por supuesto, también podemos almacenar la caché como un archivo en el disco duro, que es la forma más barata de hacerlo teniendo en cuenta la escalabilidad, y este artículo trata sobre cómo construir una caché de archivos personalizada.
1:ProveedorCacheSalida
OutputCacheProvider es una clase base abstracta que necesitamos para anular cuatro de sus métodos, que son:
Añade método para insertar el elemento especificado en la caché de salida.
Get, que devuelve una referencia al elemento especificado en la caché de salida.
Método de eliminación para eliminar el elemento especificado de la caché de salida.
Set, inserta el elemento especificado en la caché de salida y sobrescribe el elemento si está almacenado en caché.
2: Crea tu propia clase de manejo de caché de archivos
El tipo es FileCacheProvider, y el código es el siguiente:

  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. }
Copiar código
Hay dos lugares que necesitan atención especial:
En el método de Añadir, hay un juicio condicional que debe gestionarse de esta manera, de lo contrario el mecanismo de caché almacenará en caché el primer resultado, y la caché expirará después de la fecha de expiración y no se reconstruirá.
En el programa de ejemplo, simplemente ponemos la caché en el directorio de caché, y en la práctica práctica del proyecto, considerando que las páginas en caché serán miles, debemos hacer la clasificación de directorios, de lo contrario encontrar y leer archivos de caché se convertirá en un cuello de botella de eficiencia, lo que drenará la CPU.
3: Archivo de configuración

Necesitamos configurar en Web.config que el gestor de caché sea un FileCacheProvider personalizado, es decir, añadir un nodo bajo 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>
Copiar código

4: Uso de la caché

Suponemos que usarlo bajo el control de MVC (si quieres usarlo en una página de ASP.NET, incluye <% en la page@OutputCache VaryByParam="none" Duration="10" %>), y puedes ver que Index no está almacenado en caché de salida, mientras que Index2 está almacenado en caché durante 10 segundos.
  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. }
Copiar código
5: Comprueba el efecto
El código anterior, tras acceder a Index2, generará un archivo de caché en la carpeta Cache, de la siguiente manera:

Ahora, evaluemos la comparación de rendimiento entre la caché de salida y la caché de salida, simulando 100 solicitudes concurrentes de 100 usuarios de la siguiente manera:








Anterior:Ciclo de vida de la sesión
Próximo:C#. .NET para prevenir ataques de inyección SQL
Renuncia:
Todo el software, materiales de programación o artículos publicados por Code Farmer Network son únicamente para fines de aprendizaje e investigación; El contenido anterior no se utilizará con fines comerciales o ilegales; de lo contrario, los usuarios asumirán todas las consecuencias. La información de este sitio proviene de Internet, y las disputas de derechos de autor no tienen nada que ver con este sitio. Debes eliminar completamente el contenido anterior de tu ordenador en un plazo de 24 horas desde la descarga. Si te gusta el programa, por favor apoya el software genuino, compra el registro y obtén mejores servicios genuinos. Si hay alguna infracción, por favor contáctanos por correo electrónico.

Mail To:help@itsvse.com