zoukankan      html  css  js  c++  java
  • 网站优化之页面级缓存方案

    用缓存来优化网站性能的方法,估计是无人不知的。 ASP.NET提供了HttpRuntime.Cache对象来缓存数据,也提供了OutputCache指令来缓存整个页面输出。 虽然OutputCache指令使用起来更方便,也有非常好的效果, 不过,它需要我们在那些页面中添加这样一个指令。

    对于设置过OutputCache的页面来说,浏览器在收到这类页面的响应后,会将页面响应内容缓存起来。 只要在指定的缓存时间之内,且用户没有强制刷新的操作,那么就根本不会再次请求服务端, 而对于来自其它的浏览器发起的请求,如果缓存页已生成,那么就可以直接从缓存中响应请求,加快响应速度。 因此,OutputCache指令对于性能优化来说,是很有意义的(除非所有页面页面都在频繁更新)。

    在网站的优化阶段,我们可以用Fiddler之类的工具找出一些内容几乎不会改变的页面,给它们设置OutputCache, 但是,按照传统的开发流程,我们需要针对每个页面文件执行以下操作:

    方式一、使用ASP.NET平台提供的OutputCache(运行时内存)机制

    实现方式:

    1. 为列表页配置输出缓存声明;
    2. 根据页面不同的查询参数缓存不同的页面
      1. E.g.同样是列表页,分类1页面:http://www.wedn.net/cat/1/和 分类二页面:http://www.wedn.net/cat/2/分别缓存成不同的缓存对象

    优点:

    1. 配置简单、
    2. 不侵入原本系统、
    3. 访问速度非常快(因为是将执行结果缓存到内存)

    缺点:

    1. 占用资源比较多,无法缓存所有的页面。
    2. 另外有个问题:没有解决使用时间长了以后访问缓存速度变慢;

    方式二、同样使用ASP.NET平台提供的OutputCache(自定义Provider)机制

    实现方式:

    1. 开发自定义Provider程序提供给ASP.NET调用去存取输出缓存;
    2. 其余同方式一

    优点:

    1. 可以自主控制缓存读写、
    2. 不侵入原有系统、
    3. 访问快

    缺点:

    1. 配置相对复杂、
    2. 需要开发Provider
    3. 需要额外的资源(分布式缓存)

    附:

    自定义OutputCacheProvider实现将输出缓存放到分布式缓存中

    实现原理:

    实现方式:

    1. 实现抽象基类OutputCacheProvider的增删方法;
    2. 附上大概的代码(简单的通过文件读写、JSON序列化和二进制序列化实现),思路仅供参考:
    OutputCacheProvider
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Diagnostics;
      4 using System.IO;
      5 using System.Linq;
      6 using System.Runtime.Serialization.Formatters.Binary;
      7 using System.Security.Cryptography;
      8 using System.Text;
      9 using System.Web.Caching;
     10 using Micua.Utility;
     11 namespace Micua.UI.Cache
     12 {
     13     public class MicuaOutputCacheProvider : OutputCacheProvider, IDisposable
     14     {
     15         readonly IList<CacheItem> _cacheItems;
     16         public MicuaOutputCacheProvider()
     17         {
     18             if (File.Exists("z:\cache.json"))
     19             {
     20                 var json = File.ReadAllText("z:\cache.json");
     21                 _cacheItems = JsonHelper.Deserialize<List<CacheItem>>(json) ?? new List<CacheItem>();
     22             }
     23             else
     24             {
     25                 _cacheItems = new List<CacheItem>();
     26             }
     27         }
     28         public override object Get(string key)
     29         {
     30             Debug.WriteLine(string.Format("Cache.Get({0})", key));
     31             key = MD5(key);
     32             var cacheItem = _cacheItems.FirstOrDefault(c => c.Id == key);
     33             if (cacheItem != null)
     34             {
     35                 if (cacheItem.Expiration.ToUniversalTime() <= DateTime.UtcNow)
     36                 {
     37                     _cacheItems.Remove(cacheItem);
     38                 }
     39                 else
     40                 {
     41                     return Deserialize(cacheItem.Item);
     42                 }
     43             }
     44             return null;
     45         }
     46         public override object Add(string key, object entry, DateTime utcExpiry)
     47         {
     48             Debug.WriteLine("Cache.Add({0}, {1}, {2})", key, entry, utcExpiry);
     49             key = MD5(key);
     50             if (utcExpiry == DateTime.MaxValue)
     51                 utcExpiry = DateTime.UtcNow.AddMinutes(5);
     52             var item = _cacheItems.FirstOrDefault(c => c.Id == key);
     53             if (item != null)
     54             {
     55                 if (item.Expiration.ToUniversalTime() <= DateTime.UtcNow)
     56                 {
     57                     _cacheItems.Remove(item);
     58                 }
     59                 else
     60                 {
     61                     SaveChange();
     62                     return Deserialize(item.Item);
     63                 }
     64             }
     65             _cacheItems.Add(new CacheItem
     66             {
     67                 Id = key,
     68                 Item = Serialize(entry),
     69                 Expiration = utcExpiry
     70             });
     71             SaveChange();
     72             return entry;
     73         }
     74         public override void Set(string key, object entry, DateTime utcExpiry)
     75         {
     76             Debug.WriteLine("Cache.Set({0}, {1}, {2})", key, entry, utcExpiry);
     77             key = MD5(key);
     78             var item = _cacheItems.FirstOrDefault(c => c.Id == key);
     79             if (item != null)
     80             {
     81                 _cacheItems.Remove(item);
     82                 item.Item = Serialize(entry);
     83                 item.Expiration = utcExpiry;
     84                 _cacheItems.Add(item);
     85             }
     86             else
     87             {
     88                 _cacheItems.Add(new CacheItem
     89                 {
     90                     Id = key,
     91                     Item = Serialize(entry),
     92                     Expiration = utcExpiry
     93                 });
     94             }
     95             SaveChange();
     96         }
     97         public override void Remove(string key)
     98         {
     99             Debug.WriteLine("Cache.Remove({0})", key);
    100             key = MD5(key);
    101             _cacheItems.Remove(_cacheItems.FirstOrDefault(c => c.Id == key));
    102             SaveChange();
    103         }
    104         private static string MD5(string value)
    105         {
    106             var cryptoServiceProvider = new MD5CryptoServiceProvider();
    107             var bytes = Encoding.UTF8.GetBytes(value);
    108             var builder = new StringBuilder();
    109             bytes = cryptoServiceProvider.ComputeHash(bytes);
    110             foreach (var b in bytes)
    111                 builder.Append(b.ToString("x2").ToLower());
    112             return builder.ToString();
    113         }
    114         private static byte[] Serialize(object entry)
    115         {
    116             var formatter = new BinaryFormatter();
    117             var stream = new MemoryStream();
    118             formatter.Serialize(stream, entry);
    119             return stream.ToArray();
    120         }
    121         private static object Deserialize(byte[] serializedEntry)
    122         {
    123             var formatter = new BinaryFormatter();
    124             var stream = new MemoryStream(serializedEntry);
    125             return formatter.Deserialize(stream);
    126         }
    127         private void SaveChange()
    128         {
    129             var json = JsonHelper.Serialize(_cacheItems);
    130             File.WriteAllText("z:\cache.json", json);
    131         }
    132         public void Dispose()
    133         {
    134             var json = JsonHelper.Serialize(_cacheItems);
    135             File.WriteAllText("z:\cache.json", json);
    136         }
    137     }
    138 }
     
  • 相关阅读:
    JavaScript:Number 对象
    JavaScript:Math 对象
    杂项:引用资源列表
    小团队管理与大团队管理
    技术转管理
    【翻译+整理】.NET Core的介绍
    自己开发给自己用的个人知识管理工具【脑细胞】,源码提供
    关于【自证清白】
    这篇博客能让你戒烟——用程序员的思维来戒烟!
    如果我是博客园的产品经理【下】
  • 原文地址:https://www.cnblogs.com/micua/p/the-page-level-caching-scheme-of-website-optimization.html
Copyright © 2011-2022 走看看