이 글은 기계 번역의 미러 문서이며, 원본 기사로 바로 이동하려면 여기를 클릭해 주세요.

보기: 16824|회답: 0

[ASP.NET] 성능 최적화 ASP.NET 맞춤 파일 캐시를 구축하세요

[링크 복사]
게시됨 2015. 4. 19. 오후 10:06:12 | | | |
출력 캐싱(즉, 정적 HTML)ASP.NET .NET 4.0 이전까지는 메모리 기반이었습니다. 즉, 사이트에 캐시가 많으면 로컬 메모리를 쉽게 소모할 수 있다는 뜻입니다. 이제 의 도움을 받아 . .NET 4.0에서 OutputCacheProvider를 사용하면, 자체 캐시를 만들 수 있는 여러 옵션이 있습니다. 예를 들어, HTML 출력 캐시를 memcached 분산 클러스터 서버나 MongoDB(일반적으로 사용되는 문서 지향 데이터베이스, 이 http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx 참고)에 저장할 수 있습니다. 물론, 캐시를 하드 드라이브에 파일로 저장할 수도 있는데, 확장성을 고려하면 가장 저렴한 방법이며, 이 글은 맞춤형 파일 캐시를 만드는 방법에 대해 다룹니다.
1:OutputCacheProvider
OutputCacheProvider는 추상 기본 클래스로, 네 가지 메서드를 덮어써야 합니다:
지정된 항목을 출력 캐시에 삽입하는 메서드를 추가하세요.
Get 메서드는 출력 캐시에서 지정된 항목에 대한 참조를 반환합니다.
remove 메서드는 지정된 항목을 출력 캐시에서 제거하는 것입니다.
메서드를 설정하고, 지정된 항목을 출력 캐시에 삽입하고, 캐시된 항목은 덮어씁니다.
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 메서드에서는 조건부 판단이 반드시 처리되어야 하며, 그렇지 않으면 캐싱 메커니즘이 첫 번째 결과를 캐시하고, 만료일이 지나면 캐시가 만료되어 재구축되지 않습니다.
예제 프로그램에서는 단순히 캐시를 캐시 디렉터리에 넣고, 실제 프로젝트 실제로는 캐시 페이지가 수천 개에 달할 것을 고려할 때 디렉터리 분류를 해야 합니다. 그렇지 않으면 캐시 파일을 찾고 읽는 것이 효율성 병목 현상이 되어 CPU를 소모하게 됩니다.
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