龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > asp.net编程 >

使用异步缓存来保证高流量网页及时更新与低错误率

时间:2009-12-21 11:47来源:未知 作者:admin 点击:
分享到:
我通常的 WEB 开发中,有时我们会碰以这种情况,一个页面有很多模块组成,而这些模块之间是不关链的,就像一个网站的首页,里面有很多块块,有些是读新闻的,有些是读产品信息,还有一些部
     我通常的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  
 

精彩图集

赞助商链接