我通常的WEB开发中,有时我们会碰以这种情况,一个页面有很多模块组成,而这些模块之间是不关链的,就像一个网站的首页,里面有很多块块,有些是读新闻的,有些是读产品信息,还有一些部分是读论坛,博客之类的地方.而这个页面的要求是很高的,无论在什么情况下都要保证页面是可以正确打开的(当然服务器故障是没有办法的).而且网站的流量很大.
通常这样的页面是需要生成静态页来保证页面正确的,但是这种做法会有很大的问题,如果网站中一个小块异常了,会导致整个页面不更新.
现在我们给出这样一个解决方案:页面分两级缓存,一级为内存缓存,二级为文件缓存.这里的文件缓存是起辅助做用的,有一种特殊的情况,一个ASP.NET应用程序池是会重新初始化的,初始化完过后,内存数据会被清空,这个时候如果我们直接去执行数据访问程序,那么我们不能保证当时情况下程序的正确性和性能(对于程序调用过多的页面来说,执行速度慢,大量的并发请求会导致服务器崩溃).
也就是说,对于页面程序来说,如果程序一执行会先去读内存,如果发现内存为空,那么改去读相应的缓存文件,如果文件还没生成,那么再执行程序(这种情况只在程序在服务器上第一运行是发生).
为了确保页面更新及时,这里需要异步缓存,也就是说为每一个模块起一个线程来维护,如果线程方法执行成功,那么更新内存中的内容.这里建议把文件更新另起一个线程式,因为文件更新可以时间间隔长一起,结约系统资源.例如,每个模块内存更新速度是20秒,那么文件的可以设为5分钟.
下面给出一段代码,这个主要是用于缓存处理的.....
+ expand sourceview plaincopy to clipboardprint? using System; using System.Data; using System.Configuration; using System.Linq; using System.Xml.Linq; using System.IO; using System.Collections.Generic; using System.Threading; using System.Diagnostics; /// <summary> /// 本类主要负责处理根把相关参数设置缓存结果 /// </summary> public class CacheSvr { public delegate string ProcessDataDelegate(params object[] args); public static string cacheDir = "D:\tmpFile"; public static Dictionary<string, string> cacheTable = new Dictionary<string, string>(); public static ReaderWriterLockSlim lockx = new ReaderWriterLockSlim(); public static Dictionary<string, Thread> threadTable = new Dictionary<string, Thread>(); public CacheSvr() { // // TODO: Add constructor logic here // } #region 文件缓存逻辑 /// <summary> /// 保存程序执行结果致文件 /// </summary> /// <param name="thisDelegate">所要执行的方法</param> /// <param name="fileName">文件名</param> /// <param name="args">参数列表</param> /// <returns></returns> public static void saveDataFile(CacheItem item) { string result = item.doProcess(); if (result.Length > 0) { write(result, item.CacheName); } } /// <summary> /// 写文件代码 /// </summary> /// <param name="text">写入内容</param> /// <param name="fileName">文件名</param> public static void write(String text, string fileName) { try { String path = cacheDir; path = path + fileName + ".cache"; Stream fsc = File.Create(path); fsc.Close(); Stream fs = File.Open(path, FileMode.Open, FileAccess.Write); TextWriter tw = new StreamWriter(fs, System.Text.Encoding.GetEncoding(936)); tw.Write(text); tw.Close(); fs.Close(); } catch { } } public static string readFile(string fileName) { string content = ""; try { //Stopwatch watch = new Stopwatch(); //watch.Start(); String path = cacheDir; path = path + fileName + ".cache"; Stream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); StreamReader tr = new StreamReader(fs, System.Text.Encoding.GetEncoding(936)); content = tr.ReadToEnd(); //content += "\r\n <!--read from file " + path + "--> \r\n"; tr.Close(); fs.Close(); //watch.Stop(); //content = content + "<!--执行时间为:" + watch.ElapsedMilliseconds + "-->\r\n"; } catch { content = ""; } return content; } #endregion #region 内存缓存模块 /// <summary> /// 内存缓存 /// </summary> /// <param name="thisDelegate">所需执行的方法</param> /// <param name="cacheName">内存中的名字</param> /// <param name="args">参数列表</param> /// <returns></returns> public static void saveDataCache(CacheItem item) { string result = item.doProcess(); if (result.Length > 0) { cache(result, item.CacheName); } } /// <summary> /// 向内存中写入内容 /// </summary> /// <param name="text"></param> /// <param name="cacheName"></param> public static void cache(string text, string cacheName) { lockx.EnterWriteLock(); try { //text += "\r\n<!--缓存更新,时间为:" + DateTime.Now.ToString() + "-->\r\n"; cacheTable[cacheName] = text; } catch { } finally { lockx.ExitWriteLock(); } } public static void writelog(String text, string fileName) { try { String path = cacheDir; path = path + fileName + ".cache"; if (!File.Exists(path)) { Stream fsc = File.Create(path); fsc.Close(); } Stream fs = File.Open(path, FileMode.Append, FileAccess.Write); TextWriter tw = new StreamWriter(fs, System.Text.Encoding.GetEncoding(936)); tw.Write(text); tw.Close(); fs.Close(); } catch { } } public static string readCache(string cacheName) { string content = ""; lockx.EnterReadLock(); try { bool result = cacheTable.TryGetValue(cacheName, out content); //if (result) //{ // content += "\r\n <!--read from memory--> \r\n"; //} return content; } catch { return ""; } finally { lockx.ExitReadLock(); } } #endregion #region 线程处理模块 public static void UpdateCache(object obj) { CacheItem thisCache = (CacheItem)obj; writelog("线程:" + thisCache.CacheName + "--启动于:" + DateTime.Now.ToString() + "\r\n", "exceptions"); while (true) { try { saveDataCache(thisCache); } catch { } Thread.Sleep(thisCache.memoryTime * 1000);//内存20秒更新 } } public static void UpdateFile(object obj) { CacheItem thisCache = (CacheItem)obj; while (true) { try { saveDataFile(thisCache); } catch { } Thread.Sleep(thisCache.fileTime * 1000);//文件2分钟缓存 } } public static Thread getThread(string threadName) { Thread tmpThread = null; lockx.EnterReadLock(); try { if (threadTable.Keys.Contains(threadName)) { tmpThread = threadTable[threadName]; } } catch { } finally { lockx.ExitReadLock(); } return tmpThread; } /// <summary> /// 添加缓存 /// </summary> /// <param name="item">缓存对象</param> public static void saveCache(CacheItem item) { string mCacheName = item.CacheName + "_memory"; string fCacheName = item.CacheName + "_file"; Thread memoryCache = getThread(mCacheName); Thread fileCache = getThread(fCacheName); if (memoryCache == null) { memoryCache = new Thread(new ParameterizedThreadStart(UpdateCache)); memoryCache.IsBackground = true; memoryCache.Start(item); } if (fileCache == null) { fileCache = new Thread(new ParameterizedThreadStart(UpdateFile)); fileCache.IsBackground = true; fileCache.Start(item); } lockx.EnterWriteLock(); try { threadTable[mCacheName] = memoryCache; threadTable[fCacheName] = fileCache; } catch { } finally { lockx.ExitWriteLock(); } } public static string readCacheContent(CacheItem item) { //Stopwatch watch = new Stopwatch(); //watch.Start(); string content = readCache(item.CacheName); if (content==null || content.Length < 0) { content = readFile(item.CacheName); saveCache(item); } //读取缓存失败 if (content != null && content.Length <= 0) { //throw (new Exception("读取内容失败:" + item.CacheName)); content = item.doProcess(); //saveCache(item); } return content; //watch.Stop(); //content += ("\r\n<!--方法执行时间:" + watch.ElapsedMilliseconds + "-->\r\n"); } #endregion #region 公共处理 public static string saveCache(string cacheName, ProcessDataDelegate mainMathod, object[] args) { using (CacheItem tmpCache = new CacheItem()) { tmpCache.CacheName = cacheName; tmpCache.CacheDelegate = mainMathod; tmpCache.CacheArgs = args; string content = ""; content = readCacheContent(tmpCache); return content; } } #endregion } using System; using System.Data; using System.Configuration; using System.Linq; using System.Xml.Linq; using System.IO; using System.Collections.Generic; using System.Threading; using System.Diagnostics;
/// <summary> /// 本类主要负责处理根把相关参数设置缓存结果 /// </summary> public class CacheSvr { public delegate string ProcessDataDelegate(params object[] args); public static string cacheDir = "D:\tmpFile"; public static Dictionary<string, string> cacheTable = new Dictionary<string, string>(); public static ReaderWriterLockSlim lockx = new ReaderWriterLockSlim(); public static Dictionary<string, Thread> threadTable = new Dictionary<string, Thread>();
public CacheSvr() { // // TODO: Add constructor logic here // }
#region 文件缓存逻辑 /// <summary> /// 保存程序执行结果致文件 /// </summary> /// <param name="thisDelegate">所要执行的方法</param> /// <param name="fileName">文件名</param> /// <param name="args">参数列表</param> /// <returns></returns> public static void saveDataFile(CacheItem item) { string result = item.doProcess(); if (result.Length > 0) { write(result, item.CacheName); } }
/// <summary> /// 写文件代码 /// </summary> /// <param name="text">写入内容</param> /// <param name="fileName">文件名</param> public static void write(String text, string fileName) { try { String path = cacheDir; path = path + fileName + ".cache"; Stream fsc = File.Create(path); fsc.Close(); Stream fs = File.Open(path, FileMode.Open, FileAccess.Write); TextWriter tw = new StreamWriter(fs, System.Text.Encoding.GetEncoding(936)); tw.Write(text); tw.Close(); fs.Close(); } catch {
} }
public static string readFile(string fileName) { string content = ""; try { //Stopwatch watch = new Stopwatch(); //watch.Start(); String path = cacheDir; path = path + fileName + ".cache"; Stream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); StreamReader tr = new StreamReader(fs, System.Text.Encoding.GetEncoding(936)); content = tr.ReadToEnd(); //content += "\r\n <!--read from file " + path + "--> \r\n"; tr.Close(); fs.Close(); //watch.Stop(); //content = content + "<!--执行时间为:" + watch.ElapsedMilliseconds + "-->\r\n"; } catch { content = ""; } return content; } #endregion
#region 内存缓存模块 /// <summary> /// 内存缓存 /// </summary> /// <param name="thisDelegate">所需执行的方法</param> /// <param name="cacheName">内存中的名字</param> /// <param name="args">参数列表</param> /// <returns></returns> public static void saveDataCache(CacheItem item) { string result = item.doProcess(); if (result.Length > 0) { cache(result, item.CacheName); } }
/// <summary> /// 向内存中写入内容 /// </summary> /// <param name="text"></param> /// <param name="cacheName"></param> public static void cache(string text, string cacheName) { lockx.EnterWriteLock(); try { //text += "\r\n<!--缓存更新,时间为:" + DateTime.Now.ToString() + "-->\r\n"; cacheTable[cacheName] = text; } catch { } finally { lockx.ExitWriteLock(); } }
public static void writelog(String text, string fileName) { try { String path = cacheDir; path = path + fileName + ".cache"; if (!File.Exists(path)) { Stream fsc = File.Create(path); fsc.Close(); } Stream fs = File.Open(path, FileMode.Append, FileAccess.Write); TextWriter tw = new StreamWriter(fs, System.Text.Encoding.GetEncoding(936)); tw.Write(text); tw.Close(); fs.Close(); } catch {
} }
public static string readCache(string cacheName) { string content = ""; lockx.EnterReadLock(); try { bool result = cacheTable.TryGetValue(cacheName, out content); //if (result) //{ // content += "\r\n <!--read from memory--> \r\n"; //} return content; } catch { return ""; } finally { lockx.ExitReadLock(); } } #endregion
#region 线程处理模块
public static void UpdateCache(object obj) { CacheItem thisCache = (CacheItem)obj; writelog("线程:" + thisCache.CacheName + "--启动于:" + DateTime.Now.ToString() + "\r\n", "exceptions"); while (true) { try { saveDataCache(thisCache); } catch {
} Thread.Sleep(thisCache.memoryTime * 1000);//内存20秒更新 } }
public static void UpdateFile(object obj) { CacheItem thisCache = (CacheItem)obj; while (true) { try { saveDataFile(thisCache); } catch {
} Thread.Sleep(thisCache.fileTime * 1000);//文件2分钟缓存 } }
public static Thread getThread(string threadName) { Thread tmpThread = null; lockx.EnterReadLock(); try { if (threadTable.Keys.Contains(threadName)) { tmpThread = threadTable[threadName]; } } catch { } finally { lockx.ExitReadLock(); } return tmpThread; }
/// <summary> /// 添加缓存 /// </summary> /// <param name="item">缓存对象</param> public static void saveCache(CacheItem item) { string mCacheName = item.CacheName + "_memory"; string fCacheName = item.CacheName + "_file"; Thread memoryCache = getThread(mCacheName); Thread fileCache = getThread(fCacheName); if (memoryCache == null) { memoryCache = new Thread(new ParameterizedThreadStart(UpdateCache)); memoryCache.IsBackground = true; memoryCache.Start(item); } if (fileCache == null) { fileCache = new Thread(new ParameterizedThreadStart(UpdateFile)); fileCache.IsBackground = true; fileCache.Start(item); } lockx.EnterWriteLock(); try { threadTable[mCacheName] = memoryCache; threadTable[fCacheName] = fileCache; } catch { } finally { lockx.ExitWriteLock(); } }
public static string readCacheContent(CacheItem item) { //Stopwatch watch = new Stopwatch(); //watch.Start(); string content = readCache(item.CacheName); if (content==null || content.Length < 0) { content = readFile(item.CacheName); saveCache(item); } //读取缓存失败 if (content != null && content.Length <= 0) { //throw (new Exception("读取内容失败:" + item.CacheName)); content = item.doProcess(); //saveCache(item); } return content; //watch.Stop(); //content += ("\r\n<!--方法执行时间:" + watch.ElapsedMilliseconds + "-->\r\n"); } #endregion
#region 公共处理 public static string saveCache(string cacheName, ProcessDataDelegate mainMathod, object[] args) { using (CacheItem tmpCache = new CacheItem()) { tmpCache.CacheName = cacheName; tmpCache.CacheDelegate = mainMathod; tmpCache.CacheArgs = args; string content = ""; content = readCacheContent(tmpCache); return content; } } #endregion }
现在给一个使用的例子:
view plaincopy to clipboardprint? #region 广告下文字链 public static string getTopAdList(params object[] args) { BeanOper oper = new BeanOper(); StringBuilder result = new StringBuilder(); result.Append("<div class=\"ad1\">"); result.Append("<ul>"); result.Append(oper.getAdNewsHtml(3519, 1, 9, "ad1_")); result.Append("</ul>"); result.Append("<div class=\"clear\"></div>"); result.Append("</div>"); return result.ToString(); } #endregion CacheSvr.saveCache("TopAdList", new CacheSvr.ProcessDataDelegate(IndexHtml.getTopAdList), new object[] { "" })
(责任编辑:admin) |