酷易商城开发心得二、缓存应用及个人心得

news/2024/7/20 13:02:14 标签: 数据库, 内存管理

  背景:刚进行完酷易商城网站的编码工作,网站放在服务器上,给大家的第一反应就是"慢",无论是首页,还是商品详细页面的加载,给人的第一感觉很不好,该能卖东西的让这一慢也把我给吓走了!!

  发现原因:(忽略服务器宽带原因)由于酷易商城首页主要是由多个的商品列表组成,页面读取数据库次数过多,且页面中的图片数量过多,导致页面加载速度过慢,首先想到的就是使用缓存,目前主要是页面缓存和数据缓存。

  实践:(asp.net)想到缓存时,对于首页首先想到了页面缓存,这种缓存使用很简单,只需在页头添加以下代码即可:

<%@ OutputCache Duration="7200" Location="Any" VaryByCustom="browser" VaryByParam="none" %>

此项就是asp.net页面缓存的使用方式,下面列出几个常用参数(详细的建议F1下查msdn)

OutputCache参数

Duration,设定页面缓存持续时间,单位是秒(太可怜了)。

Location,指定页面缓存保存的位置,Any为默认。

VaryByCustom,当此项设为browser时,允许我们根据浏览器的名称和主版本信息缓存不同版本。也可以把它设为一个自定义方法的名称,从而实现我们自己的逻辑,控制缓存的版本。

VaryByParam,通过此项可以设置当前页面缓存依赖的参数,为none表示不根据参数缓存,如果页面有商品参数id,此处可设置为VaryByParam="id",有多个时可填写多项。

 

通过上面的方式,把首页的加载速度很快就提了起来,自己也很高兴,但第二天有人反应首页购物车及搜索不好用了,我还纳闷,这些都是之前测试好的啊,中午吃饭时突然才想到,酷易商城首页应用了页面缓存...这下子就找出了原因,页面缓存是针对整个页面进行状态输出的,所以文本框及购物车状态都是不变的,想到后立马就换,接下来该是数据缓存上场了!

  数据缓存,即为保存在服务器端内存的数据,客户端加载数据时只要缓存存在,就直接从服务器内存中读取数据,而不用再进行数据库的读取操作(在下也就理解到这里了),所以数据缓存也是广大程序员非常喜欢的利器。接下来就以实例说一下我手下的缓存。

  首先说一下系统设计结构,为了快速开发,自己整理了些系统开发中常用的功能模块,当然,缓存操作也包括在内,整个类不大,在此贴出来:

ContractedBlock.gif ExpandedBlockStart.gif Code
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Web.Caching;
 5using System.Web;
 6
 7namespace Koyee.Common
 8ExpandedBlockStart.gifContractedBlock.gif{
 9    public class CacheHelp
10ExpandedSubBlockStart.gifContractedSubBlock.gif    {
11
12ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// 简单创建/修改Cache,前提是这个值是字符串形式的
13        /// <summary>
14        /// 简单创建/修改Cache,前提是这个值是字符串形式的
15        /// </summary>
16        /// <param name="strCacheName">Cache名称</param>
17        /// <param name="strValue">Cache值</param>
18        /// <param name="iExpires">有效期,秒数(使用的是当前时间+秒数得到一个绝对到期值)</param>
19        /// <param name="priority">保留优先级,1最不会被清除,6最容易被内存管理清除(1:NotRemovable;2:High;3:AboveNormal;4:Normal;5:BelowNormal;6:Low)</param>

20        public static void Insert(string strCacheName, object strValue, int iExpires, int priority)
21ExpandedSubBlockStart.gifContractedSubBlock.gif        {
22            //TimeSpan ts = new TimeSpan(0, 0, iExpires);
23            CacheItemPriority cachePriority;
24            switch (priority)
25ExpandedSubBlockStart.gifContractedSubBlock.gif            {
26                case 6:
27                    cachePriority = CacheItemPriority.Low;
28                    break;
29                case 5:
30                    cachePriority = CacheItemPriority.BelowNormal;
31                    break;
32                case 4:
33                    cachePriority = CacheItemPriority.Normal;
34                    break;
35                case 3:
36                    cachePriority = CacheItemPriority.AboveNormal;
37                    break;
38                case 2:
39                    cachePriority = CacheItemPriority.High;
40                    break;
41                case 1:
42                    cachePriority = CacheItemPriority.NotRemovable;
43                    break;
44                default:
45                    cachePriority = CacheItemPriority.Default;
46                    break;
47            }

48            HttpContext.Current.Cache.Insert(strCacheName, strValue, null, DateTime.Now.AddHours(iExpires), System.Web.Caching.Cache.NoSlidingExpiration, cachePriority, null);
49        }

50
51ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// 简单读书Cache对象的值
52        /// <summary>
53        /// 简单读书Cache对象的值
54        /// </summary>
55        /// <param name="strCacheName">Cache名称</param>
56        /// <returns>Cache字符串值</returns>

57        public static object Get(string strCacheName)
58ExpandedSubBlockStart.gifContractedSubBlock.gif        {
59            if (HttpContext.Current.Cache[strCacheName] == null)
60ExpandedSubBlockStart.gifContractedSubBlock.gif            {
61                return null;
62            }

63            return HttpContext.Current.Cache[strCacheName];
64        }

65
66ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// 删除Cache对象
67        /// <summary>
68        /// 删除Cache对象
69        /// </summary>
70        /// <param name="strCacheName">Cache名称</param>

71        public static void Del(string strCacheName)
72ExpandedSubBlockStart.gifContractedSubBlock.gif        {
73            HttpContext.Current.Cache.Remove(strCacheName);
74        }

75
76    }

77}

以上就是缓存操作类,需要声明的一点就是,这里把缓存时间默认为了以小时为单位,这是酷易商城系统决定的。

通过以上静态方法就可以非常方便的进行缓存操作,首先看一下首页商品列表的缓存加载,关键代码如下:

StartLoad( 1 , Productlists,  "   Substring(Pro_State, 1, 1) = 1 and  Pro_Audit=1  " " 1 " " index.pro_com " 10 ); // 推荐商品绑定

调用方法下:

ContractedBlock.gif ExpandedBlockStart.gif Code
protected void StartLoad(int PageIndex, Repeater rep, string strWhere, string ClassID, string type, int count)
        {
            
string cacheName = listcacheName + type;
            
if (CacheHelp.Get(cacheName) == null)
            {
                DataTable data;
                
//此处为信息查询
                CacheHelp.Insert(cacheName, data, 3003);//把查询数据输入到缓存中
            }
            rep.DataSource 
= CacheHelp.Get(cacheName) as DataTable;
            
//设置数据源
            rep.DataBind();
        }

通过几行代码就可以实现对首页单个列表数据的缓存,同理可对其他列表数据进行操作。

荐:为了系统中缓存的维护,推荐把系统中用到的缓存单独保存在类中,或是以常量(const)形式来保存,也可以提高一点效率。

以上是首页列表缓存,下面来看一下单个产品的缓存。

提前预想到要处理的问题:酷易商城中的商品是个容易变动的信息,所以要使当前商品显示立即更新,就要做好对单个商品缓存更新的处理操作,可以把此过程封装在业务层(Business)。贴下代码:

private   static   readonly   string  CACHENAME  =   " Koyee.ProductModel-D- " ; // 此为商品缓存名称前缀,以便进行区分

为了使缓存统一管理,定义了商品缓存的前缀名称,即上面代码。

具体的操作代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
 1public Koyee.Model.Product GetProductByCache(int id)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 3            string CacheKey = CACHENAME + id;
 4            object objModel = CommonQ.DataCache.GetCache(CacheKey);
 5            if (objModel == null)
 6ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 7                try
 8ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 9                    objModel = IPC.GetId(id);//重新获取信息
10                    if (objModel != null)
11ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
12                        CommonQ.DataCache.SetCache(CacheKey, objModel, DateTime.Now.AddDays(3), TimeSpan.Zero);
13                    }

14                }

15ExpandedSubBlockStart.gifContractedSubBlock.gif                catch { }
16            }

17            return (Koyee.Model.Product)objModel;
18        }

19
20        public void RemoveProductDCache(int id)
21ExpandedBlockStart.gifContractedBlock.gif        {
22            string CacheKey = CACHENAME + id.ToString();
23            CommonQ.DataCache.Del(CacheKey);
24        }

代码很简单,需要注意的就是,当商品更新时需要将当前修改商品缓存进行更新,简单的方法就是更新完商品后重新调用一下获取商品的方法,更懒的方法就是修改业务层:在修改方法执行完后直接调用获取方法(有的朋友是在修改完后直接删除缓存,让客户浏览时再次加载,不过这样做总感觉不好)。

附:为了使操作人员手工进行缓存清除操作,可调用方法来清除系统中的缓存,代码如下:

IDictionaryEnumerator c  =  Cache.GetEnumerator(); // 获取当前缓存

                
while  (c.MoveNext())
                {
                    Cache.Remove(c.Key.ToString());
                }

 

总结:通过酷易商城系统中缓存处理的简单介绍,希望对大家有所帮助,欢迎大家前来指点

 

转载于:https://www.cnblogs.com/quluqi/archive/2009/10/23/1588784.html


http://www.niftyadmin.cn/n/1395782.html

相关文章

真正的inotify+rsync实时同步 彻底告别同步慢

背景 我们公司在用inotifyrsync做实时同步&#xff0c;来解决分布式集群文件一致性的问题。但当web文件越来越多(百万级数量html,jpg等小 文件)&#xff0c;同步就越来越慢&#xff0c;根本做不到实时&#xff0c;按照网上的调优方法都尝试过&#xff0c;问题根本没有解决。经过…

系统中毒的现象

最近&#xff0c;好多朋友都说我的QQ游戏不能玩,有时会蓝屏,还有死机,首先和他们进行了硬盘扫描,内存检测都通过了&#xff0c;就怀疑是系统中毒了&#xff0c;给他们重新安装了一下问题解决了。但是但是还有一种问题就是QQ游戏频繁要升级&#xff0c;还有好多补丁和留洞一起要…

shell脚本之获取其它进程的标准输出

一 将当前命令&#xff08;进程&#xff09;的标准输出重定向到其它命令&#xff08;进程&#xff09;的标准输入 通过管道符“|”将当前命令&#xff08;进程&#xff09;标准输出重定向到其它命令&#xff08;进程&#xff09;的标准输入 [zhaominyonglocalhost yum.repos.d…

mysql新建用户,用户授权,删除用户,修改密码

mysql有几个图形管理软件很好用&#xff0c;比如mysql-front &#xff0c;phpadmin等等&#xff0c;简单易用&#xff0c;这里就不做介绍了。另外eclipse有个数据库管理的插件叫&#xff0c;可以对各种常用的数据库进行图形管理&#xff0c;也很好用。 下面步入正题&#xff0c…

《网络工程师考试辅导》纠错(2)

由于本人水平所限&#xff0c;《网络工程师考试辅导》中难免存在各式各样的错误。请各位读者不吝赐教&#xff0c;将您发现的问题或错误列举出来&#xff0c;以便我和广大读者们及时更正。 我交稿时图片是采用visio画的&#xff0c;而出版社印刷采用的其他的排版系统&#xff0…

Linux启动新进程的三种方法

程序中&#xff0c;我们有时需要启动一个新的进程&#xff0c;来完成其他的工作。 下面介绍了三种实现方法&#xff0c;以及这三种方法之间的区别。 1.system函数-调用shell进程&#xff0c;开启新进程 system函数&#xff0c;是通过启动shell进程&#xff0c;然后执行shell…

linux下如何创建守护进程的步骤

1&#xff0c;进程的概念&#xff1a;程序的一次动态执行过程。 进程存在于内存当中&#xff0c;存在着 创建&#xff0c;调度&#xff0c;执行和消亡&#xff0c;进程号是进程的唯一标志&#xff0c;每一个进程都有自己独立的内存空间&#xff0c;在32位操作系统中&#xf…

man rsync翻译(rsync命令中文手册)

rsync(1) 名称rsync - 一个快速、多功能的远程(和本地)文件拷贝工具摘要Local: rsync [OPTION...] SRC... [DEST]Access via remote shell:Pull: rsync [OPTION...] [USER]HOST:SRC... [DEST]Push: rsync [OPTION...] SRC... [USER]HOST:DESTAccess via rsync daemon:Pull:…