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, η οποία επιστρέφει μια αναφορά στο καθορισμένο στοιχείο στην κρυφή μνήμη εξόδου. Καταργήστε τη μέθοδο για να αφαιρέσετε το καθορισμένο στοιχείο από την προσωρινή μνήμη εξόδου. Set μέθοδος, εισάγει το καθορισμένο στοιχείο στην κρυφή μνήμη εξόδου και αντικαθιστά το στοιχείο εάν είναι αποθηκευμένο στην κρυφή μνήμη.
2: Δημιουργήστε τη δική σας κλάση χειρισμού προσωρινής αποθήκευσης αρχείων Ο τύπος είναι FileCacheProvider και ο κωδικός είναι ο εξής:
- public class FileCacheProvider : OutputCacheProvider
- {
- private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- public override void Initialize(string name, NameValueCollection attributes)
- {
- base.Initialize(name, attributes);
- CachePath = HttpContext.Current.Server.MapPath(attributes["cachePath"]);
- }
-
- public override object Add(string key, object entry, DateTime utcExpiry)
- {
- Object obj = Get(key);
- if (obj != null) //这一步很重要
- {
- return obj;
- }
- Set(key,entry,utcExpiry);
- return entry;
- }
-
- public override object Get(string key)
- {
- string path = ConvertKeyToPath(key);
- if (!File.Exists(path))
- {
- return null;
- }
- CacheItem item = null;
- using (FileStream file = File.OpenRead(path))
- {
- var formatter = new BinaryFormatter();
- item = (CacheItem)formatter.Deserialize(file);
- }
-
- if (item.ExpiryDate <= DateTime.Now.ToUniversalTime())
- {
- log.Info(item.ExpiryDate + "*" + key);
- Remove(key);
- return null;
- }
- return item.Item;
- }
-
-
- public override void Set(string key, object entry, DateTime utcExpiry)
- {
- CacheItem item = new CacheItem(entry, utcExpiry);
- string path = ConvertKeyToPath(key);
- using (FileStream file = File.OpenWrite(path))
- {
- BinaryFormatter formatter = new BinaryFormatter();
- formatter.Serialize(file, item);
- }
- }
-
- public override void Remove(string key)
- {
- string path = ConvertKeyToPath(key);
- if (File.Exists(path))
- File.Delete(path);
- }
-
- public string CachePath
- {
- get;
- set;
- }
-
- private string ConvertKeyToPath(string key)
- {
- string file = key.Replace('/', '-');
- file += ".txt";
- return Path.Combine(CachePath, file);
- }
- }
-
- [Serializable]
- public class CacheItem
- {
- public DateTime ExpiryDate;
- public object Item;
-
- public CacheItem(object entry, DateTime utcExpiry)
- {
- Item = entry;
- ExpiryDate = utcExpiry;
- }
- }
Αντιγραφή κώδικα Υπάρχουν δύο μέρη που χρειάζονται ιδιαίτερη προσοχή: Στη μέθοδο Προσθήκη, υπάρχει μια υπό όρους κρίση που πρέπει να αντιμετωπιστεί με αυτόν τον τρόπο, διαφορετικά ο μηχανισμός προσωρινής αποθήκευσης θα αποθηκεύσει προσωρινά το πρώτο αποτέλεσμα και η προσωρινή μνήμη θα λήξει μετά την ημερομηνία λήξης και δεν θα ξαναχτιστεί. Στο παράδειγμα προγράμματος, απλώς βάζουμε την κρυφή μνήμη στον κατάλογο της κρυφής μνήμης και στην πραγματική πρακτική του έργου, λαμβάνοντας υπόψη ότι οι αποθηκευμένες σελίδες θα είναι χιλιάδες, πρέπει να κάνουμε ταξινόμηση καταλόγου, διαφορετικά η εύρεση και η ανάγνωση αρχείων προσωρινής μνήμης θα γίνει συμφόρηση αποτελεσματικότητας, η οποία θα εξαντλήσει την CPU.
3: Αρχείο διαμόρφωσης
Πρέπει να ρυθμίσουμε στο Web.config ότι ο χειριστής προσωρινής μνήμης είναι ένας προσαρμοσμένος FileCacheProvider, δηλαδή να προσθέσουμε έναν κόμβο κάτω από το FileCacheProvider:- <caching>
- <outputCache defaultProvider="FileCache">
- <providers>
- <add name="FileCache" type="MvcApplication2.Common.FileCacheProvider" cachePath="~/Cache" />
- </providers>
- </outputCache>
- </caching>
Αντιγραφή κώδικα
4: Χρήση προσωρινής μνήμης
Υποθέτουμε ότι η χρήση του στον έλεγχο του MVC (αν θέλετε να το χρησιμοποιήσετε σε μια σελίδα ASP.NET, συμπεριλάβετε το <% στο page@OutputCache VaryByParam="none" Duration="10" %>) και μπορείτε να δείτε ότι το Index δεν είναι αποθηκευμένο στην κρυφή μνήμη, ενώ το Index2 είναι αποθηκευμένο στην κρυφή μνήμη εξόδου για 10 δευτερόλεπτα.
- public class HomeController : Controller
- {
- private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- static string s_conn = "Data Source=192.168.0.77;Initial Catalog=luminjidb;User Id=sa;Password=sa;";
- public ActionResult Index()
- {
- 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()"))
- {
- ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
- }
- return View();
- }
-
- [OutputCache(Duration = 10, VaryByParam = "none")]
- public ActionResult Index2()
- {
- 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()"))
- {
- ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
- }
- return View();
- }
- }
Αντιγραφή κώδικα 5: Ελέγξτε το εφέ Ο παραπάνω κώδικας, μετά την πρόσβαση στο Index2, θα δημιουργήσει ένα αρχείο προσωρινής μνήμης στο φάκελο Cache, ως εξής:
Τώρα, ας αξιολογήσουμε τη σύγκριση απόδοσης μεταξύ της κρυφής μνήμης εξόδου και της κρυφής μνήμης εξόδου, προσομοιώνοντας 100 ταυτόχρονα αιτήματα από 100 χρήστες ως εξής:
|